02 OAuth 流程与浏览器认证 本节摘要:远程 MCP server 往往要求授权(「你得先登录才能用我的工具」)。本节讲 OpenCode 如何处理 MCP server 的 OAuth 授权流程——启动本地回调服务、引导用户去浏览器登录、处理回调拿令牌。还有动态客户端注册、CSRF 防护这些安全细节。理解了本节,你才知道「为什么连某个 MCP server 时会弹浏览器让我登录」。 一、为什么 MCP server 要授权 很多有价值的 MCP server 背后是受保护的数据/服务——比如 Google Drive MCP 要访问你的文档、Slack MCP 要发消息。这些操作不能让任意客户端随便调,必须确认你是谁、你授权了。
本节摘要:远程 MCP server 往往要求授权(「你得先登录才能用我的工具」)。本节讲 OpenCode 如何处理 MCP server 的 OAuth 授权流程——启动本地回调服务、引导用户去浏览器登录、处理回调拿令牌。还有动态客户端注册、CSRF 防护这些安全细节。理解了本节,你才知道「为什么连某个 MCP server 时会弹浏览器让我登录」。
很多有价值的 MCP server 背后是受保护的数据/服务——比如 Google Drive MCP 要访问你的文档、Slack MCP 要发消息。这些操作不能让任意客户端随便调,必须确认你是谁、你授权了。
最常见的授权方式就是 OAuth——你见过「用 Google 登录」「用 GitHub 登录」那种流程,MCP server 用的就是这套。OpenCode 作为 MCP 客户端,要帮用户走完这个流程,拿到访问令牌,之后才能调 server 的工具。
一次完整的 MCP OAuth 流程大致是:
1. OpenCode 连 MCP server ──► server 说「需要授权」(needs_auth) │ 2. OpenCode 启动本地回调服务(监听某本地端口) │ 3. OpenCode 打开浏览器,引导用户去 server 的授权页 │ 4. 用户在浏览器登录并授权 │ 5. server 把授权码回调到 OpenCode 的本地回调服务 │ 6. OpenCode 用授权码换访问令牌 │ 7. 之后调 server 工具都带上这个令牌
💡 为什么启动本地回调服务:OAuth 流程里,server 授权完要把「授权码」送回客户端。送回的方式是「重定向到一个回调地址」。OpenCode 启动一个本地小服务监听(如
127.0.0.1:某端口作为回调地址,server 重定向过来时它就能接住。
有个进阶情况:有些 server 不认识你的客户端,要求先「注册客户端」(needs_client_registration)。OAuth 有个「动态客户端注册」机制,让客户端在运行时向 server 注册自己,拿到 client_id。
OpenCode 支持这个——如果 server 要求客户端注册,OpenCode 会自动走动态注册流程,注册完再继续授权。有些 server 也支持「预注册 clientId」(提前在 server 配好),OpenCode 也兼容。
连 server: │ ├─ server 认识客户端 ──► 直接授权流程 │ └─ server 要注册(needs_client_registration) │ ▼ 动态客户端注册 拿到 client_id │ ▼ 继续授权流程
OAuth 流程有个安全隐患——CSRF(跨站请求伪造)。攻击者可能用自己的授权码「偷梁换柱」,让你不知不觉授权了攻击者的资源。OpenCode 通过 state 参数( oauth state) 防护:
发起授权: 带 state=随机X ▼ 回调: 必须带回 state=X ▼ OpenCode 校验: 回调state == X? ──► 是才接受
这防住了「攻击者塞自己授权码」的 CSRF 攻击。
本地回调服务不会一直开着——它有超时(如 5 分钟)。如果用户在浏览器里磨蹭太久(或放弃了),回调服务超时关闭,这次授权失败,需要重来。
启动回调服务(超时 5 分钟) │ ├─ 5 分钟内收到回调 ──► 拿令牌,关闭服务 │ └─ 超时未收到 ──► 关闭服务,授权失败
⚠️ 超时是保护:回调服务不能无限期开着(那是资源泄漏和安全隐患)。超时让它自动关闭,用户没及时完成就重来——这是合理的设计。
拿到访问令牌后,OpenCode 会存起来(安全存储),下次连同一个 server 时复用,不用每次都走完整 OAuth:
第一次连 server X ──► 走完整 OAuth ──► 拿到令牌 ──► 存储 │ 下次连 server X ──► 检查存了令牌吗 ──► 有就用它,不重走 OAuth │ 令牌过期/失效 ──► 重新走 OAuth
OpenCode 提供了一组方法管理这套:hasStoredTokens(有没有存令牌)、getAuthStatus(认证状态)、startAuth/finishAuth/removeAuth(发起/完成/移除认证)、supportsOAuth(server 支不支持 OAuth)。
这里要澄清一个分工——OAuth 认证 vs 第 4 章权限,都管「能不能」,但层面不同:
| 机制 | 管什么 |
|---|---|
| OAuth 认证(本节) | 你是谁(身份),server 让不让你用 |
| 第 4 章权限 | 你能干什么(操作),OpenCode 让不让你调某工具 |
OAuth 解决「server 认不认你」,权限解决「OpenCode 让不让你调」。一个 MCP 工具,即使 OAuth 通过了(server 认你),如果 OpenCode 权限规则是 deny,你依然调不了——两层都要过。
传输和认证都讲了,下一节讲 MCP 工具如何进入注册表、如何受权限约束。