1. OAuth2.0 核心概念:六大角色与令牌
OAuth2.0 是一种授权框架,它允许第三方应用(客户端)在资源所有者(用户)的授权下,安全地访问其托管在资源服务器上的受保护资源,而无需暴露用户的长期凭证(如密码)。理解其核心概念是掌握整个框架的基石。
整个协议围绕以下六个核心要素展开:资源所有者、客户端、授权服务器、资源服务器、访问令牌、刷新令牌。
1.1 四大核心角色
| 角色 | 定义 | 典型示例 |
|---|---|---|
| 资源所有者 (Resource Owner) |
拥有受保护资源的实体,通常是用户。它能够授权客户端访问其资源。 | 你(用户)授权“某照片打印App”访问你存储在“Google相册”中的照片。 |
| 客户端 (Client) |
代表资源所有者请求访问受保护资源的第三方应用。它需要获得授权才能操作。 | “某照片打印App”(Web应用、移动App、单页应用等)。 |
| 授权服务器 (Authorization Server) |
负责认证资源所有者并颁发访问令牌的服务器。它是整个授权流程的核心枢纽。 | Google 的认证服务 (accounts.google.com),负责验证你的身份并颁发令牌。 |
| 资源服务器 (Resource Server) |
托管受保护资源的服务器。它验证访问令牌的有效性,并根据令牌中的权限决定是否提供服务。 | Google Photos API 的后端服务,验证令牌后返回你的照片数据。 |
💡 关键区分:授权服务器与资源服务器在逻辑上是分离的,但在物理部署上可以合并。例如,一个微服务既可以承担授权职责,也可以承担资源服务职责,但为了安全和解耦,生产环境中通常建议分开部署。
1.2 两种核心令牌
令牌是 OAuth2.0 中代表授权凭证的字符串,客户端通过令牌来访问资源。主要有两种类型:
| 令牌类型 | 作用 | 生命周期 | 安全考量 |
|---|---|---|---|
| 访问令牌 (Access Token) |
客户端用来直接访问资源服务器的凭证。资源服务器通过验证此令牌来授权数据访问。 | 短生命周期(通常几分钟到几小时),降低泄露风险。 | 对资源服务器是不透明的(通常为随机字符串或 JWT),客户端不应解析其内部结构。 |
| 刷新令牌 (Refresh Token) |
用于在访问令牌过期后,向授权服务器获取新的访问令牌,而无需用户重新授权。 | 长生命周期(通常数天到数月),甚至可持久化。 | 必须安全存储(如服务端、安全存储区),因为它可以生成新的访问令牌。刷新令牌本身不直接访问资源。 |
🔑 令牌生命周期管理最佳实践:
- 访问令牌:设置较短的过期时间(如 15-30 分钟),减少令牌泄露后的攻击窗口。
- 刷新令牌:设置较长的过期时间(如 7-30 天),并实现轮换策略(每次刷新后颁发新的刷新令牌,旧的立即失效)。
- 在微服务架构中,资源服务器应本地验证访问令牌(如 JWT 签名验证),避免每次请求都回查授权服务器,提升性能。
1.3 核心概念关系总结
下图展示了六大概念之间的逻辑依赖关系,帮助建立整体认知:
⚠️ 常见误解澄清:
- 访问令牌 ≠ 用户身份:访问令牌是授权凭证,不是身份凭证。它告诉资源服务器“这个客户端被允许做什么”,而不是“用户是谁”。用户身份通常通过 ID Token (OpenID Connect) 传递。
- 刷新令牌不是万能药:刷新令牌虽然生命周期长,但不应永久有效。应结合业务安全策略(如检测异常IP、设备变化)决定是否允许刷新。
- 客户端凭证 ≠ 用户凭证:在客户端凭证模式中,客户端以自己的身份(而非用户身份)获取令牌,适用于服务间通信。
1.4 核心概念速查表
以下速查表帮助你在调试和设计时快速回顾每个概念的关键属性:
| 概念 | 是否存储凭证 | 是否直接暴露给用户 | 主要交互对象 | 典型协议端点 |
|---|---|---|---|---|
| 资源所有者 | 是(用户名/密码等) | — | 授权服务器、客户端 | /authorize (用户交互) |
| 客户端 | 是(client_id / client_secret) | 部分(client_id 公开,secret 保密) | 授权服务器、资源服务器 | /token, /revoke |
| 授权服务器 | 是(用户凭证、客户端凭证) | 否 | 资源所有者、客户端 | /authorize, /token, /introspect |
| 资源服务器 | 否(验证令牌) | 否 | 客户端 | 受保护 API 端点 |
| 访问令牌 | 否(由授权服务器签发) | 否(客户端持有) | 资源服务器 | 作为 Bearer Token 在 HTTP Header 中传递 |
| 刷新令牌 | 否(由授权服务器签发) | 否(客户端安全存储) | 授权服务器 | /token (grant_type=refresh_token) |