AI接口鉴权用API Key还是OAuth

文章导读
先给一个判断方向:如果调用方是你自己的后端服务,凭证代表的是“这个应用”,用 API Key 通常就够;如果凭证要代表“某个用户”去访问 AI 资源,或者用户需要看到、管理、撤销这份授权,就应该走 OAuth。混合做法也很常见——面向用户的入口走 OAuth,内部服务之间继续用 API Key。
📋 目录
  1. 壹 先确认当前场景和目标
  2. 贰 按这个顺序处理
  3. 叁 改完后怎么验证
  4. 肆 容易忽略的边界
A A

先给一个判断方向:如果调用方是你自己的后端服务,凭证代表的是“这个应用”,用 API Key 通常就够;如果凭证要代表“某个用户”去访问 AI 资源,或者用户需要看到、管理、撤销这份授权,就应该走 OAuth。混合做法也很常见——面向用户的入口走 OAuth,内部服务之间继续用 API Key。

判断依据不是“哪个更安全”,而是“凭证代表谁”。代表应用、只在服务端之间传递、生命周期由自己掌控,选 API Key,并把密钥放进环境变量或密钥管理服务,禁止下发到前端。代表用户、需要用户同意与撤销、需要按人区分配额和权限,选 OAuth 的授权码流程,服务端保存 refresh token,前端只拿短期凭证。两者都不解决传输加密和日志泄露问题,需要额外处理。

先确认当前场景和目标

在动代码之前,先把下面几个问题答清楚,答案基本决定了选型,而不是反过来先选协议再找场景。

  • 调用方是谁:浏览器、移动端、你自己的后端服务,还是第三方开发者接入你的平台。浏览器和移动端属于不可信环境,长期凭证不应落在其中。
  • 凭证代表谁:代表一个应用(机器身份),还是一个具体用户(用户身份)。代表用户就要能回答“这个用户授权了什么、能撤销吗”。
  • 是否需要用户同意:用户是否要看到授权页面、是否要按范围授予权限。需要就落在 OAuth 的授权码流程里。
  • 生命周期与轮换:密钥多久换一次、泄露后多久能失效、能否按环境隔离。API Key 通常需要自己设计轮换机制,OAuth 的 access token 天生短期。
  • 权限粒度:是否要区分“只能调用某几个模型”“只能读不能写”“按用户限额”。粗粒度用 Key 加白名单可以,细粒度按人区分建议走 OAuth 的 scope。

如果以上问题里出现“用户要撤销”“要按人计费”“要第三方接入”,基本可以确定需要 OAuth。如果只是自家后端调自家 AI 网关,先上 API Key,把精力放在密钥管理上更划算。

按这个顺序处理

建议按“先定身份 → 再定存放 → 再定校验 → 最后补轮换”的顺序推进,避免一开始就纠结协议细节。

第一步:写清凭证的身份和边界

用一句话描述凭证:谁持有、能调哪些接口、有效期多长、泄露后如何作废。这句话写不出来,说明场景还没定,先别写代码。

第二步:API Key 的落地骨架

密钥只放在服务端环境变量或密钥管理服务里,代码中不出现明文。下面是通用骨架,变量名按你的项目替换:

# .env(不要提交到仓库)
AI_API_KEY=replace-with-your-key
AI_BASE_URL=https://your-ai-gateway.example.com

# 服务端发起请求时注入请求头
Authorization: Bearer ${AI_API_KEY}
# 部分平台用自定义头,按实际网关约定替换头名
X-Api-Key: ${AI_API_KEY}

前端代码、构建产物、移动端安装包中都不应出现这把 Key。如果前端需要调用 AI 能力,让前端调你自己的后端,由后端持有 Key 再转发。

AI接口鉴权用API Key还是OAuth

第三步:OAuth 的落地骨架

面向用户的场景走授权码流程,服务端换 token,浏览器只拿短期 access token 或干脆只拿会话 Cookie:

# 1) 引导用户授权(scope 按最小权限填写)
GET /authorize?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://your-app.example.com/callback
  &scope=ai.read
  &state=RANDOM_STATE

# 2) 回调后用 code 换 token(服务端执行)
POST /token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=RETURNED_CODE
&redirect_uri=https://your-app.example.com/callback
&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET

返回的 refresh token 存服务端,access token 只在内存或短期存储中使用。state 参数要校验,回调地址要白名单,这两点常被漏掉。

第四步:混合场景的分层

常见做法是外层 OAuth 识别用户,内层用一个独立的后端 API Key 去调 AI 服务。这样用户侧可以撤销授权,同时 AI 服务的凭证不会因为用户退出而失效。两层凭证放在不同组件里,不要串用。

第五步:补上轮换和撤销

API Key 至少准备“新旧双活”的过渡方案:先加新 Key,观察调用方切换完成,再停旧 Key。OAuth 侧确认 refresh token 的失效逻辑和解绑入口真的可用。

改完后怎么验证

验证要看信号,不要只看“能调通”。以下动作建议逐条执行:

  • 不带任何凭证请求受保护接口,预期返回 401,而不是 200 或 500。
  • 用一把已作废或过期的 Key 请求,预期返回 401,并确认错误信息里不回显 Key 内容。
  • 用 scope 不足的 token 请求超出范围的接口,预期返回 403,且提示缺少哪个范围。
  • 在 OAuth 流程中篡改 state 或回调地址,预期被拒绝,不进入发码环节。
  • 在服务端日志、网关日志、异常上报中搜索密钥片段,预期查不到明文;如果查得到,先处理日志脱敏再继续。
  • 对前端构建产物做一次关键字扫描,确认没有出现密钥字符串。
  • 走一遍用户撤销授权的流程,预期后续请求被拒绝,且不会静默降级成共享 Key。

预期信号是:越权和缺失凭证都表现为明确的 401/403,而不是业务错误码或超时。出现后者通常说明鉴权层放在了业务逻辑之后,需要前移。

容易忽略的边界

  • OAuth 不等于加密:OAuth 解决的是授权委托和凭证生命周期,传输仍然要靠 HTTPS,token 泄露后的风险主要靠短期有效期控制。
  • 浏览器和移动端不适合长期凭证:把 API Key 打进前端包里,等同于公开。此类场景建议改为后端持有凭证,或走带 PKCE 的授权码流程;具体支持情况需要结合你使用的平台确认。
  • 反向代理和网关会记录请求头:鉴权头经过多层转发时,注意哪些中间层会落日志。必要时在网关层剥离或脱敏后再转发。
  • 多环境隔离:开发、测试、线上使用不同 Key 和不同 OAuth 客户端,避免测试流量打到线上配额。
  • 不适用条件:如果团队没有密钥管理能力,也没有人力维护 token 刷新和轮换,先收敛到单一 API Key 加固定出口,比半套 OAuth 更稳。
  • 回退建议:切换过程中保留旧鉴权方式一段时间,用开关控制,确认新链路稳定后再关闭;出问题时能快速切回,而不用回滚整个版本。