☰
为什么 ChatGPT App 需要身份验证与 OAuth 的简要演进
2026/10/11 14:40:06 网站建设 项目流程

1. 为什么 ChatGPT App 需要身份验证

先说重点:ChatGPT 中的用户 ≠ 你服务中的用户。

ChatGPT 有它自己的用户账号。你的服务有自己的 userId、tenantId、角色、计费、订单。两者之间并没有默认的“魔法”关联。 如果你只是启动了一个 MCP 服务器并定义了几个 tools,ChatGPT 会把它们当作某个抽象客户端来调用。

回到我们的示例应用 GiftGenius——一个帮助挑选礼物和管理愿望单的 ChatGPT App。我们希望做到:

  • 向用户展示其已保存的礼物清单。
  • 允许将礼物标记为“已购买”或“已收到”。
  • 展示订单历史(尤其是之后要接入 commerce/ACP 时)。

没有身份验证时,MCP 服务器完全不知道“这是谁”。它最多只能看到一些连接的技术性标识和一个 OpenAI 提供的匿名 subject(用于标识与限流),而且官方明确提醒不要把它用于授权。

身份验证 vs 授权

先把两个概念分清非常有用。

  • 身份验证(AuthN)回答的问题是:这是谁?
  • 授权(AuthZ)回答的问题是:这个“谁”被允许做什么?

对 ChatGPT App 而言,大致流程如下:

  1. 先通过 OAuth 确认用户确实已在你的 IdentityProvider(IdP,如 Keycloak/Auth0)登录,并获取带有其标识的令牌。这是身份验证。
  2. 随后 MCP 服务器读取令牌,从中提取 sub、角色和其他 claims,并据此决定该用户是否可以调用具体的工具(如 list_orders、delete_profile 等)。这是授权。

在代码层面可(简化后)这样理解:

// MCP 服务器希望掌握的用户信息类型 export interface AuthContext { userId: string; roles: string[]; } // 在 tool 处理器中的用法示例 async function listGiftLists(auth: AuthContext | null) { if (!auth) { throw new Error("User is not authenticated"); } // 只从数据库取出该用户的清单 return db.giftLists.findMany({ where: { ownerId: auth.userId } }); }

没有 userId 和角色,你就无法正确编写业务逻辑。一切都会沦为“所有人共用一个大账号”。

2. 为什么“把 API Key 放进 .env”不是解决方案

作为开发者,我们有个本能反应:“做个 API Key,放进 .env,就都能跑了”。确实,对服务到服务(service-to-service)的内部集成而言,API Key 是合适的工具。但一旦涉及真实用户与 ChatGPT App,“一个密钥通吃”的做法就会崩盘。

回顾早些模块里的典型代码,我们只是从 MCP 打到自己的后端:

// mcp/backendClient.ts export const backendClient = new BackendClient({ baseUrl: process.env.BACKEND_URL!, apiKey: process.env.BACKEND_API_KEY!, // 整个 ChatGPT 共用一个密钥 });

对后端而言,现在所有请求看起来都一样:“这是 ChatGPT 集成”。“玛莎”和“帕沙”之间没有任何差别。于是:

  • 无法显示“个人中心”——服务器不知道它属于谁。
  • 无法区分权限:“这个用户只能读,那个用户还能下单”。
  • 无法把订单绑定到具体的人(在你的主系统里)。

在 MCP 世界里,这也不安全。规范建议通过 Streamable HTTP 使用 HTTP 认证(Bearer、API Key 等),但强调用户访问受保护资源时,最好使用 OAuth 与令牌,而不是单一的服务密钥。

另外,从 OpenAI 的政策看,一个好的应用应只请求确有必要的数据,并让用户掌控与 App 共享的内容。这与 OAuth 的 scopes 模型高度契合,却与“一个全能超级密钥”的思路背道而驰。

在 ChatGPT 语境下,服

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询