3. OAuth2.0 四种授权模式对比:授权码模式、隐式模式、密码模式、客户端凭证模式,以及 PKCE 扩展
OAuth2.0 协议定义了四种核心授权模式,分别适用于不同的客户端类型与安全场景。此外,PKCE(Proof Key for Code Exchange) 作为授权码模式的重要安全扩展,已成为移动端与单页应用的首选方案。本章将从流程、适用场景、安全等级三个维度进行系统对比。
3.1 四种授权模式核心流程对比
下表从参与者、凭证传递方式、令牌获取步骤三个关键维度,对四种模式进行横向对比:
| 授权模式 | 典型客户端 | 用户凭证是否暴露给客户端 | 是否需要客户端密钥 | 令牌传递方式 | 安全等级 |
|---|---|---|---|---|---|
| 授权码模式 | Web 服务端应用 | 否(通过授权码中转) | 是 | 后端通道(Back Channel) | ★★★★★ |
| 隐式模式 | 浏览器单页应用(SPA) | 否(直接返回令牌) | 否 | 前端通道(Front Channel) | ★★★☆☆ |
| 密码模式 | 受信任的第一方应用 | 是(直接传递用户名密码) | 是 | 后端通道 | ★★☆☆☆ |
| 客户端凭证模式 | 服务间通信(M2M) | 不涉及用户 | 是 | 后端通道 | ★★★★☆ |
安全提示: 隐式模式因令牌直接暴露在浏览器 URL 片段中,已不推荐用于新应用。OAuth2.0 Security BCP(Best Current Practice)建议使用授权码模式 + PKCE 替代隐式模式。
3.2 授权码模式(Authorization Code Grant)
授权码模式是 OAuth2.0 中最完整、最安全的流程。它通过授权码作为临时凭证,在客户端与授权服务器之间建立安全的后端通道,避免访问令牌暴露在用户代理(浏览器)中。
3.3 隐式模式(Implicit Grant)
隐式模式专为浏览器单页应用(SPA)设计,授权服务器直接返回访问令牌,省略了授权码交换步骤。由于令牌直接暴露在 URL 片段中,存在令牌泄露和中间人攻击风险。
弃用警告: 根据 OAuth 2.0 Security BCP(RFC 9700),隐式模式已被标记为“不推荐使用”。所有新开发的 SPA 应使用授权码模式 + PKCE。
3.4 密码模式(Resource Owner Password Credentials Grant)
密码模式允许客户端直接收集用户的用户名和密码,并以此向授权服务器换取访问令牌。该模式仅适用于高度信任的第一方应用,例如操作系统级应用或官方移动客户端。
- 优点: 流程简单,一次请求即可获取令牌。
- 缺点: 客户端直接接触用户明文密码,一旦客户端被攻破,所有用户凭证将泄露。
- 适用场景: 迁移旧系统、内部工具、受信任的官方应用。
3.5 客户端凭证模式(Client Credentials Grant)
客户端凭证模式用于服务到服务(M2M)的通信场景,不涉及用户。客户端使用自己的 client_id 和 client_secret 直接向授权服务器请求令牌。
// 客户端凭证模式请求示例
POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=your_client_id
&client_secret=your_client_secret
&scope=read write
可观测性要点: 在 Mock 服务中,客户端凭证模式是最容易模拟的模式。你可以在 Mock 响应中注入延迟、错误码、限流响应,以测试下游服务的容错能力。
3.6 PKCE 扩展(Proof Key for Code Exchange)
PKCE(RFC 7636)是授权码模式的安全增强扩展,专门解决公共客户端(如移动 App、SPA)无法安全存储 client_secret 的问题。它通过动态生成的 code_verifier 和 code_challenge 替代静态密钥。
| PKCE 参数 | 说明 | 生成方式 |
|---|---|---|
code_verifier |
客户端生成的随机字符串(43~128 字符) | crypto.randomBytes(32).toString('base64url') |
code_challenge |
code_verifier 的变换值 |
base64url(sha256(code_verifier)) |
code_challenge_method |
变换方法(S256 或 plain) |
推荐使用 S256 |
3.7 四种模式 + PKCE 选型决策树
在实际项目中,选择哪种授权模式取决于客户端类型、安全要求和用户交互方式。以下决策树可帮助你快速判断:
- 是否涉及用户?
- 否 → 使用 客户端凭证模式
- 是 → 进入下一步
- 客户端是否能安全存储密钥?
- 是(Web 服务端) → 使用 授权码模式
- 否(SPA / 移动 App) → 使用 授权码模式 + PKCE
- 是否是完全受信任的第一方应用?
- 是 → 可考虑 密码模式(但优先推荐授权码模式)
- 否 → 禁止使用密码模式
Mock 服务实战建议: 在构建 OAuth2.0 Mock 服务时,建议优先实现授权码模式 + PKCE 和 客户端凭证模式。这两种模式覆盖了 90% 以上的现代应用场景。密码模式和隐式模式可作为兼容性端点保留,但应在文档中标注为“遗留模式”。