OAuth 2.1 几种授权流程,一次性讲清
OAuth 相关概念很多,但团队里真正高频、也最容易混淆的,其实就是几条核心流程。把它们放到同一张图景里看,选型、边界和实现位置都会清晰很多。
先说结论
先把结论放前面:
- 面向用户登录的主流程,默认选
authorization_code + PKCE。 - 面向机器调用的主流程,默认选
client_credentials。 - 受限输入设备选
device_authorization。 refresh_token不是初始授权流程,而是已有授权结果的续期机制。implicit和resource owner password credentials不应该再作为新系统方案。
还有一条经常会被混到一起:
token_exchange很常见,但它不是 OAuth 2.1 的核心主流程,而是 RFC 8693 定义的扩展能力,适合网关、代理和服务间换票。
OAuth 2.1 到底是什么
截至 2026 年 5 月 18 日,IETF Datatracker 上的 OAuth 2.1 仍是 Internet-Draft draft-ietf-oauth-v2-1-15,发布时间是 2026 年 3 月 2 日。它的方向不是“发明一套全新协议”,而是把 OAuth 2.0 这些年已经被业界验证过的安全实践收敛成默认基线。
可以把它理解成两件事:
- 保留真正还值得用的流程
- 把过去那些容易泄漏 token、边界含混、实现成本高且经常做错的模式移除或弱化
配套的安全背景,建议同时看 OAuth Security BCP,也就是 RFC 9700。这份 BCP 明确总结了哪些模式已经不适合继续推广。

先用这张图建立整体心智模型:
- 有用户,且能正常走浏览器:
authorization_code + PKCE - 有用户,但终端不方便登录:
device_authorization - 没有用户,纯服务自己干活:
client_credentials - 已经拿到授权结果,要续期:
refresh_token - 已经有一个可信 token,想换成另一个 audience 的 token:
token_exchange
1. Authorization Code + PKCE

这是现在最应该优先掌握的流程,也是大多数用户登录型系统的默认答案。
适用场景
- Web 应用
- 单页应用(SPA)
- 移动端 App
- 桌面客户端
核心过程
- 客户端把用户导到授权服务器。
- 客户端发起
/authorize请求,携带code_challenge、state、scope等参数。 - 用户在授权服务器侧完成登录和授权确认。
- 授权服务器通过重定向把
authorization code发回客户端。 - 客户端再走后端通道请求
/token,提交code + code_verifier。 - 授权服务器校验通过后,返回
access_token,可选返回refresh_token和id_token。
为什么 PKCE 现在是默认项
因为授权码本身不能再被当作“只要截到就能换 token”的东西。
PKCE 的本质是:
- 前面发起授权请求时先承诺一个 challenge
- 真正换 token 时再拿出原始 verifier
这样即使授权码在重定向链路里被截获,攻击者也无法仅凭授权码完成换 token。
安全重点
redirect_uri精确匹配state防 CSRF 和混淆- PKCE 必开
- token 只从后端通道返回,不走浏览器 URL
refresh_token尽量做轮换
2. Client Credentials

这是最容易被误用的一种流程。它的本意非常简单:客户端代表自己,不代表某个用户。
适用场景
- 定时任务
- 服务治理组件
- 后台控制面
- 内部服务调用受保护 API
核心过程
- 服务自己调用
/token。 grant_type=client_credentials。- 通过
client_secret、private_key_jwt、mTLS 等方式完成客户端认证。 - 授权服务器返回
access_token。 - 服务用这个 token 调下游 API。
常见误用
- 用它替代用户授权
- 给太宽的 scope
- 把长期 token 当成静态密钥使用
实践重点
- 尽量缩 scope
- 尽量缩 audience
- TTL 不要过长
- 尽量提升 client authentication 强度
3. Device Authorization Grant

这是设备码流程,适合输入能力差、但又确实存在用户授权动作的终端。
适用场景
- TV
- 机顶盒
- 命令行工具
- 智能屏
- 终端设备
核心过程
- 设备先向授权服务器申请
device_code和user_code。 - 授权服务器返回
verification_uri、user_code、轮询间隔等信息。 - 设备把
user_code和访问地址展示给用户。 - 用户在另一台更适合登录的浏览器里打开验证页,输入
user_code,完成登录和批准。 - 设备按约定频率轮询
/token。 - 在用户完成批准前,设备会收到
authorization_pending。 - 批准后,设备才拿到
access_token,可选拿到refresh_token。
这条流程的关键点
用户认证和设备取 token 是两条链路:
- 用户认证发生在可信浏览器
- 设备只负责拿码、展示码、轮询 token
这也是为什么 CLI、TV 这类终端能安全接入统一登录体系。
安全重点
device_code和user_code的熵要足够user_code过期和终态要明确- 轮询间隔要受控,过快要返回
slow_down - 批准动作必须和登录态、上下文、设备请求绑定
4. Refresh Token

严格说,refresh_token 不是一条“第一次拿授权”的主流程,而是一条“已有授权结果后的续期链路”。
它解决的矛盾
访问令牌应该短寿命,否则泄漏窗口太大。
但如果 access token 太短,用户每几分钟重新登录一次也不可接受。
所以典型做法是:
- access token 短 TTL
- refresh token 用来换新的 access token
核心过程
- 客户端发现 access token 过期或即将过期。
- 客户端调用
/token,grant_type=refresh_token。 - 授权服务器校验 refresh token 和客户端归属。
- 返回新的 access token。
- 更稳妥的做法是同时返回新的 refresh token,也就是 refresh token rotation。
安全重点
- refresh token 只发给真正需要续期能力的客户端
- refresh token 不应该暴露给资源服务器
- 建议做轮换
- 建议做撤销与异常检测
5. Token Exchange

这条流程经常出现在企业网关、代理层和服务网格里,但它不是 OAuth 2.1 主体的一部分,而是 RFC 8693 定义的扩展。
它要解决什么
现实系统里,一个服务常常已经拿到某个“上游可信 token”,但这个 token:
- audience 不对
- scope 太大
- 来源域不一致
- 不适合直接给下游继续用
这时就会做 token exchange:
- 拿一个已有 token 或主体断言
- 去授权服务器换一张新的、面向特定 audience 的 token
典型场景
- API Gateway 用用户登录态换内部服务 token
- Service A 拿到外部 IdP token,再换成内部域 token
- BFF 或代理层把用户 token 换成下游专用 token
安全重点
- 明确
subject_token的来源和可信边界 - 明确新 token 的 audience
- 明确缩 scope,而不是原样放大复制
- 明确谁有资格做 exchange
为什么 Implicit 和 Password 不再推荐
Implicit Grant
implicit 的问题不是“完全不能实现”,而是它把 access token 暴露在前端重定向链路里,带来更多泄漏面,例如:
- 浏览器历史
- 地址栏
- 前端日志
- 引用头(Referer)
- 各种第三方脚本和中间跳转
现在 authorization_code + PKCE 已经可以覆盖浏览器类客户端,就没有必要继续推广 implicit。
Resource Owner Password Credentials
password 模式的问题更根本:客户端自己向用户要密码。
这会直接破坏 OAuth 里最重要的一层边界:
- 用户不再只把凭据交给授权服务器
- 客户端本身变成了密码采集点
- 上游登录策略、MFA、风控、凭据演进都更难统一
所以今天讨论新系统,默认就不应再把它当候选项。
参考资料
- OAuth 2.1 draft: https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/15/
- OAuth 2.0 Security Best Current Practice, RFC 9700: https://www.rfc-editor.org/rfc/rfc9700
- OAuth 2.0 Device Authorization Grant, RFC 8628: https://www.rfc-editor.org/rfc/rfc8628
- OAuth 2.0 Token Exchange, RFC 8693: https://www.rfc-editor.org/rfc/rfc8693

浙公网安备 33010602011771号