3. OAuth2.0 基础回顾:四种授权模式与 Token 类型
OAuth2.0 是目前业界标准的授权协议,它允许第三方应用在用户授权的前提下,安全地访问受保护资源,而无需暴露用户的长期凭证(如密码)。理解 OAuth2.0 的四种授权模式以及 Token 类型,是构建安全、可扩展后端缓存体系的前提。
3.1 四种授权模式对比
OAuth2.0 根据客户端类型(机密/公开)和信任级别,定义了四种授权模式。下表从安全性、适用场景和 Token 获取流程三个维度进行对比:
| 授权模式 | 客户端类型 | 安全性等级 | 典型场景 | 是否需要 Refresh Token |
|---|---|---|---|---|
| 授权码模式 | 机密客户端(有后端服务器) | 最高 | Web 应用、移动端原生应用(通过 PKCE 增强) | 是 |
| 隐式模式 | 公开客户端(纯前端) | 低(已不推荐) | 单页应用(SPA,已被授权码+PKCE 取代) | 否(直接返回 Access Token) |
| 密码模式 | 高度信任的客户端 | 中 | 第一方应用、遗留系统迁移 | 是 |
| 客户端凭证模式 | 机密客户端(无用户参与) | 高(仅限机器间通信) | 微服务间调用、后台任务、API 网关 | 视 Token 有效期而定 |
3.2 授权码模式(核心模式)
授权码模式是 OAuth2.0 中最安全、最完整的授权流程。它通过一个临时的“授权码”作为中间凭证,确保 Access Token 只在安全的后端通道中传输,避免了 Token 在前端暴露的风险。
下图展示了授权码模式的标准交互流程:
3.3 隐式模式(已不推荐)
隐式模式是授权码模式的简化版,它直接返回 Access Token,跳过了授权码交换步骤。由于 Access Token 直接暴露在 URL 片段中,存在被浏览器历史记录、Referer 头等泄露的风险。目前业界已普遍使用授权码模式 + PKCE(Proof Key for Code Exchange)来替代隐式模式。
3.4 密码模式
密码模式允许客户端直接使用用户的用户名和密码换取 Token。这种模式要求客户端高度可信(通常是第一方应用),因为它直接接触用户的明文密码。在微服务架构中,密码模式常用于内部服务间的快速集成,但应尽量避免在第三方应用中使用。
// 密码模式 Token 请求示例
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=password
&username=user@example.com
&password=secret_password
&client_id=your_client_id
&client_secret=your_client_secret
3.5 客户端凭证模式
客户端凭证模式是唯一不需要用户参与的授权模式。客户端使用自己的身份凭证(client_id + client_secret)直接向授权服务器申请 Token。这种模式适用于微服务之间的内部通信、定时任务、后台批处理等场景。
// 客户端凭证模式 Token 请求示例
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=service-a
&client_secret=service-a-secret
&scope=read:orders write:orders
3.6 Token 类型详解
OAuth2.0 定义了两种核心 Token 类型:Access Token 和 Refresh Token。它们在生命周期、用途和缓存策略上存在显著差异。
| 属性 | Access Token | Refresh Token |
|---|---|---|
| 用途 | 访问受保护资源 | 获取新的 Access Token |
| 有效期 | 短(通常 15 分钟 - 1 小时) | 长(通常 7 天 - 30 天) |
| 存储位置 | 客户端内存或安全存储 | 客户端安全存储(如 HttpOnly Cookie) |
| 缓存策略 | 高频访问,需快速失效 | 低频访问,需持久化存储 |
| 失效方式 | 过期、用户登出、权限变更 | 过期、用户登出、Refresh Token 轮换 |
| 缓存一致性要求 | 高(需实时同步失效) | 中(可容忍短暂不一致) |
下图展示了 Access Token 与 Refresh Token 在缓存中的生命周期管理:
3.7 缓存一致性设计原则
基于上述四种授权模式和 Token 类型,后端缓存一致性设计应遵循以下原则:
- 授权码缓存: 使用 Redis 等分布式缓存,设置极短 TTL(30-60 秒),使用后立即删除,防止重放攻击。
- Access Token 缓存: 设置 TTL 为 Token 有效期的 70%-80%,在 TTL 到期前通过后台任务或懒加载方式主动刷新。
- Refresh Token 缓存: 设置 TTL 为 Token 有效期的 90%,并实现 Refresh Token 轮换机制(每次刷新返回新的 Refresh Token,旧 Token 立即失效)。
- 缓存失效广播: 当用户主动登出、密码变更或权限更新时,通过消息队列(如 Redis Pub/Sub 或 Kafka)广播 Token 失效事件,确保所有缓存节点同步清除相关 Token。
- 客户端凭证缓存: 在微服务网关层实现集中式 Token 缓存,避免每个服务实例独立缓存导致的冗余和一致性问题。
access_token:{user_id} 和 refresh_token:{user_id})分别管理。