2. OAuth2.0核心概念:资源所有者、客户端、授权服务器、资源服务器、访问令牌、刷新令牌

OAuth2.0 协议定义了六种核心角色与构件,它们共同构成了授权交互的完整闭环。理解这些概念是进行 API 契约治理的基础——每一份契约都需要明确指定这些角色的交互边界与令牌生命周期。

2.1 六大核心概念总览

下表从契约治理视角对比各角色的职责与关键属性:

概念 角色/构件 契约治理关注点 典型示例
资源所有者 角色 授权范围声明、用户确认流程 终端用户
客户端 角色 client_id 注册、redirect_uri 白名单 Web 应用、移动 App
授权服务器 角色 令牌端点、授权端点、密钥管理 Auth0、Keycloak
资源服务器 角色 令牌验证、scope 校验、API 契约 REST API 网关
访问令牌 构件 格式(JWT/不透明)、有效期、scope access_token
刷新令牌 构件 轮换策略、撤销机制、存储安全 refresh_token
契约治理提示: 在 API 契约中,资源服务器与授权服务器之间的令牌验证接口(如 introspection endpoint)必须作为契约的一部分显式定义,否则会导致生产环境中的授权黑洞。

2.2 核心交互流程

下图展示了 OAuth2.0 授权码模式下六个核心概念之间的典型交互顺序:

OAuth2.0 核心概念交互流程 OAuth2.0 核心概念交互流程(授权码模式) 资源所有者 客户端 授权服务器 资源服务器 访问令牌 刷新令牌 ① 授权请求 ② 授权码请求 ③ 授权码 ④ 令牌请求 ⑤ 访问令牌+刷新令牌 ⑥ API请求(携带访问令牌) ⑦ 受保护资源响应 ⑧ 刷新令牌(令牌过期后) 说明:虚线表示可选或条件触发流程;刷新令牌仅在访问令牌过期且授权服务器支持时使用。

2.3 角色详解

2.3.1 资源所有者(Resource Owner)

资源所有者是能够授予对受保护资源访问权限的实体。在大多数场景中,资源所有者就是终端用户。契约治理中需要明确资源所有者授权的方式(如用户点击确认按钮、输入密码等),以及授权范围的粒度。

  • 授权方式: 授权码、隐式、密码、客户端凭证
  • 契约要求: 授权页面必须展示明确的 scope 列表,且用户可撤销授权
  • 安全约束: 资源所有者的凭证(如密码)不得直接传递给客户端

2.3.2 客户端(Client)

客户端是代表资源所有者发起受保护资源请求的应用程序。客户端需要在授权服务器上注册,获取唯一的 client_id 和可选的 client_secret。

契约治理关键点: 客户端的 redirect_uri 必须在授权服务器上严格注册并校验,防止开放重定向攻击。API 契约中应明确列出所有允许的重定向 URI 模式。

2.3.3 授权服务器(Authorization Server)

授权服务器负责验证资源所有者的身份,获取授权,并向客户端颁发令牌。它是 OAuth2.0 体系中的核心信任锚点。

端点 用途 契约治理要求
/authorize 资源所有者授权端点 必须支持 response_type、client_id、redirect_uri、scope、state 参数
/token 令牌颁发端点 必须支持 grant_type、code、redirect_uri、client_id 参数
/introspect 令牌 introspection(RFC 7662) 资源服务器调用,验证令牌活跃状态与 scope
/revoke 令牌撤销端点(RFC 7009) 支持客户端主动撤销令牌

2.3.4 资源服务器(Resource Server)

资源服务器托管受保护资源,接收并验证访问令牌,然后响应资源请求。在微服务架构中,每个 API 网关或后端服务都可能是一个资源服务器。

  • 令牌验证方式: 本地验证(JWT 签名校验)或远程验证(调用 introspection 端点)
  • 契约要求: 资源服务器必须校验令牌的 scope 是否包含所需权限
  • 常见错误: 仅校验令牌有效性,忽略 scope 校验,导致权限越界

2.4 令牌详解

2.4.1 访问令牌(Access Token)

访问令牌是客户端用于访问受保护资源的凭证。它通常具有较短的有效期(如 15 分钟到 1 小时),以减少泄露风险。

属性 说明 契约治理建议
格式 JWT 或不透明字符串 推荐 JWT 格式,便于资源服务器本地验证
有效期 通常 15-60 分钟 根据业务安全等级调整,越短越安全
scope 权限范围列表 必须与资源所有者授权时的 scope 一致
签名 JWT 使用 RS256 或 HS256 生产环境推荐 RS256,支持公钥分发

2.4.2 刷新令牌(Refresh Token)

刷新令牌用于在访问令牌过期后获取新的访问令牌,而无需资源所有者重新授权。刷新令牌通常具有更长的有效期(如 7 天到 30 天),且支持轮换策略。

安全警告: 刷新令牌必须安全存储,不得在 URL 参数中传输。推荐使用刷新令牌轮换(Refresh Token Rotation)机制——每次使用刷新令牌后,授权服务器同时返回一个新的刷新令牌,并使旧的刷新令牌失效。

刷新令牌的典型使用流程:

  1. 客户端检测到访问令牌过期(HTTP 401 响应)
  2. 客户端向授权服务器的 /token 端点发送 grant_type=refresh_token 请求
  3. 授权服务器验证刷新令牌的有效性
  4. 授权服务器返回新的访问令牌(和可选的新的刷新令牌)
  5. 客户端使用新的访问令牌重新请求资源

2.5 令牌生命周期与契约治理

从契约治理角度,令牌的生命周期必须在 API 契约中显式定义:

// 契约示例:令牌响应结构(OAuth2.0 标准)
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def50200...",
  "scope": "read write"
}
  • expires_in: 访问令牌的有效期(秒),契约中必须明确该字段的语义
  • scope: 令牌实际拥有的权限范围,资源服务器必须校验
  • refresh_token: 可选字段,契约中应说明是否支持刷新令牌以及轮换策略
最佳实践: 在 API 契约中为令牌验证接口(introspection)定义明确的响应格式,包括 active、scope、client_id、exp 等字段。这可以避免资源服务器与授权服务器之间的集成歧义。

2.6 核心概念关系总结

下图展示了六个核心概念之间的依赖与数据流关系:

OAuth2.0 核心概念关系图 OAuth2.0 核心概念关系图 资源所有者 客户端 授权服务器 资源服务器 访问令牌 刷新令牌 授权 请求令牌 颁发令牌 携带访问令牌请求资源 持有 生成 生成 用于刷新