02 OAuth 流程与浏览器认证


文档摘要

02 OAuth 流程与浏览器认证 本节摘要:远程 MCP server 往往要求授权(「你得先登录才能用我的工具」)。本节讲 OpenCode 如何处理 MCP server 的 OAuth 授权流程——启动本地回调服务、引导用户去浏览器登录、处理回调拿令牌。还有动态客户端注册、CSRF 防护这些安全细节。理解了本节,你才知道「为什么连某个 MCP server 时会弹浏览器让我登录」。 一、为什么 MCP server 要授权 很多有价值的 MCP server 背后是受保护的数据/服务——比如 Google Drive MCP 要访问你的文档、Slack MCP 要发消息。这些操作不能让任意客户端随便调,必须确认你是谁、你授权了。

02 OAuth 流程与浏览器认证

本节摘要:远程 MCP server 往往要求授权(「你得先登录才能用我的工具」)。本节讲 OpenCode 如何处理 MCP server 的 OAuth 授权流程——启动本地回调服务、引导用户去浏览器登录、处理回调拿令牌。还有动态客户端注册、CSRF 防护这些安全细节。理解了本节,你才知道「为什么连某个 MCP server 时会弹浏览器让我登录」。

一、为什么 MCP server 要授权

很多有价值的 MCP server 背后是受保护的数据/服务——比如 Google Drive MCP 要访问你的文档、Slack MCP 要发消息。这些操作不能让任意客户端随便调,必须确认你是谁、你授权了

最常见的授权方式就是 OAuth——你见过「用 Google 登录」「用 GitHub 登录」那种流程,MCP server 用的就是这套。OpenCode 作为 MCP 客户端,要帮用户走完这个流程,拿到访问令牌,之后才能调 server 的工具。

二、OAuth 流程全景

一次完整的 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 │ ▼ 继续授权流程

四、CSRF 防护

OAuth 流程有个安全隐患——CSRF(跨站请求伪造)。攻击者可能用自己的授权码「偷梁换柱」,让你不知不觉授权了攻击者的资源。OpenCode 通过 state 参数( oauth state) 防护:

  • 发起授权时,OpenCode 生成一个随机 state
  • server 授权完回调时必须带回这个 state
  • OpenCode 校验回调的 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,你依然调不了——两层都要过。

八、本节要点回顾

  1. 远程 MCP server 常要 OAuth 授权:确认身份才能用受保护的数据/服务。
  2. 流程:连 server → 启动本地回调服务 → 浏览器登录授权 → 回调拿授权码 → 换令牌。
  3. 本地回调服务:监听本地端口接 server 重定向,有超时(约 5 分钟)。
  4. 动态客户端注册:server 不认识客户端时自动注册拿 client_id。
  5. CSRF 防护:用 state 参数校验,防攻击者偷梁换柱。
  6. 令牌存储复用:存起来下次复用,过期才重走 OAuth。
  7. 与权限分工:OAuth 管身份(server 认不认你),权限管操作(OpenCode 让不让你调)。

传输和认证都讲了,下一节讲 MCP 工具如何进入注册表、如何受权限约束。


发布者: 作者: 灏天文库 转发
评论区 (0)
U