2. 刷新令牌流程概述:从授权码到访问令牌,再到刷新令牌的完整时序图

OAuth 2.0 刷新令牌流程并非一个独立协议,而是建立在授权码流程之上的令牌生命周期管理机制。理解完整时序是定位错误码的前提——只有知道每一步的预期输入与输出,才能准确断言故障发生在哪个环节。

2.1 核心角色与令牌类型

在进入时序图之前,先明确参与方与令牌的语义差异:

角色/令牌 缩写 说明
资源拥有者 RO 通常为终端用户,授权客户端访问其受保护资源
客户端 Client 请求令牌的应用程序(Web、移动、单页)
授权服务器 AS 颁发授权码、访问令牌、刷新令牌,并验证凭证
资源服务器 RS 持有受保护资源,验证访问令牌后返回数据
授权码 code 一次性凭证,有效期极短(通常 1~10 分钟)
访问令牌 AT 用于访问资源,有效期短(通常 15~60 分钟)
刷新令牌 RT 用于获取新的访问令牌,有效期长(数小时到数天)
关键断言: 刷新令牌仅在授权码流程的令牌端点颁发时返回。隐式流程不颁发刷新令牌,这是初学者最容易忽略的约束。

2.2 完整时序图:从授权码到刷新令牌

下图展示了从用户授权开始,经过授权码交换、访问令牌获取,再到刷新令牌使用的完整生命周期。图中使用标准 OAuth 2.0 端点命名:/authorize、/token、/protected。

OAuth 2.0 授权码 + 刷新令牌完整时序图 授权码 → 访问令牌 → 刷新令牌 完整时序 资源拥有者 客户端 授权服务器 资源服务器 1. 授权请求 2. 用户认证 & 授权 3. 授权码 (code) 4. 令牌请求 5. 颁发 AT + RT 6. 访问资源 (AT) 7. 返回资源 8. AT 过期 9. 刷新请求 (RT) 10. 颁发新 AT 11. 继续访问 (新 AT) 步骤 5 是刷新令牌 唯一颁发时机 步骤 9 使用 grant_type=refresh_token

2.3 流程步骤分解

将上述时序拆解为 11 个可断言步骤,每个步骤对应一个 HTTP 请求/响应或状态转换:

  1. 授权请求 — 客户端构造 /authorize 请求,包含 response_type=code、client_id、redirect_uri、scope。
  2. 用户认证与授权 — 资源拥有者在授权服务器登录,并同意客户端请求的权限范围。
  3. 授权码返回 — 授权服务器通过重定向将 code 发送到客户端的 redirect_uri。
  4. 令牌请求 — 客户端向 /token 端点发送 grant_type=authorization_code,附带 code、redirect_uri、client_id、client_secret。
  5. 颁发访问令牌与刷新令牌 — 授权服务器验证授权码有效后,返回 access_token、refresh_token、expires_in、token_type。
  6. 访问资源 — 客户端使用 access_token 请求资源服务器的受保护 API。
  7. 返回资源 — 资源服务器验证令牌有效后返回数据。
  8. 访问令牌过期 — 客户端收到 401 Unauthorized 或 403 Forbidden,或通过 expires_in 预判过期。
  9. 刷新请求 — 客户端向 /token 端点发送 grant_type=refresh_token,附带 refresh_token、client_id、client_secret。
  10. 颁发新访问令牌 — 授权服务器验证刷新令牌有效后,返回新的 access_token,可选返回新的 refresh_token(轮换策略)。
  11. 继续访问 — 客户端使用新访问令牌再次请求资源。

2.4 令牌端点请求/响应对比

授权码交换与刷新令牌使用同一个 /token 端点,但请求参数不同。下表对比两个关键请求:

参数 授权码交换 刷新令牌
grant_type authorization_code refresh_token
code 必填,授权码值 不出现
refresh_token 不出现 必填,刷新令牌值
redirect_uri 必填,必须与授权请求一致 可选(部分实现忽略)
client_id 必填(公开客户端) 必填(公开客户端)
client_secret 必填(机密客户端) 必填(机密客户端)
响应差异 返回 access_token + refresh_token 返回 access_token,refresh_token 可选
故障定位要点: 如果客户端在步骤 5 的响应中没有收到 refresh_token,则后续步骤 9~11 无法执行。常见原因包括:授权服务器配置未启用刷新令牌、scope 不包含 offline_access、或客户端类型被判定为不适合颁发刷新令牌。

2.5 刷新令牌的两种生命周期策略

刷新令牌的过期与轮换策略直接影响错误码的触发时机。以下是两种主流实现:

  • 固定过期策略 — 刷新令牌有一个固定的 expires_in(如 30 天),过期后必须重新走授权码流程。错误码 invalid_grant 会在刷新令牌过期时返回。
  • 轮换策略 — 每次使用刷新令牌时,授权服务器同时返回一个新的刷新令牌,并使旧的刷新令牌失效。如果客户端重复使用旧刷新令牌,授权服务器返回 invalid_grant,并可能使所有关联的刷新令牌失效(防重放攻击)。
常见陷阱: 轮换策略下,如果客户端在步骤 10 没有保存新的刷新令牌,而旧的刷新令牌已被废弃,则下一次刷新必然失败。这是生产环境中 invalid_grant 错误的高发原因之一。

2.6 时序中的关键错误码触发点

以下列出时序图中每个步骤可能出现的标准 OAuth 2.0 错误码,作为后续章节深入分析的索引:

步骤 可能错误码 典型原因
3 access_denied 用户拒绝授权
4 invalid_grant 授权码已过期、已使用、redirect_uri 不匹配
5 invalid_client client_id 或 client_secret 无效
6 invalid_token 访问令牌格式错误、过期、签名无效
9 invalid_grant 刷新令牌过期、已被轮换、被撤销
9 invalid_client 客户端凭证无效或客户端被禁用
10 invalid_scope 请求的 scope 超出原始授权范围