Refresh Token(刷新令牌)详解

在第五章中,刷新令牌(Refresh Token) 的引入是为了解决“安全”与“用户体验”之间的矛盾。访问令牌(Access Token)通常有效期很短(如 1 小时),如果过期后要用户重新登录,体验会很糟糕。刷新令牌则允许客户端在后台偷偷“续期”。

以下是它的业务逻辑和具体案例:

1. 刷新令牌的业务逻辑流程

刷新令牌的逻辑主要分为 “获取”“使用” 两个阶段:

阶段一:获取(伴随访问令牌一起发放)

  1. 用户授权:用户同意授权后,客户端拿着授权码(Code)去授权服务器换令牌。

  2. 双证齐发:授权服务器验证通过,返回一个 JSON 包,里面不仅有 access_token,还有一个 refresh_token

  3. 持久化存储:客户端将 access_token 存入临时缓存,将 refresh_token 安全地存入数据库(因为它的有效期通常很长,几天甚至几个月)。

阶段二:使用(访问令牌过期时)

  1. 请求失败:客户端拿着 access_token 请求资源服务器,收到 401 Unauthorized 错误。

  2. 后台静默续期:客户端不再跳转到登录页,而是直接向授权服务器的 令牌端点 发起 POST 请求:

    • 参数包含:grant_type=refresh_tokenrefresh_token=xxxx

    • 同时需要提供客户端的身份证明(Client ID 和 Secret)。

  3. 验证并翻新:授权服务器检查 refresh_token 是否有效、是否被撤回。验证通过后,颁发一个新的 access_token(有时也会滚动更新 refresh_token)。

  4. 重试请求:客户端拿到新令牌,重新发起之前失败的 API 请求。


2. 举个具体的例子:音乐播放器应用

假设你开发了一个叫 “悦动音乐” 的 App,它需要访问 “网盘 API” 来播放用户存储在云端的 MP3 文件。

  • 第一步:初次结缘(授权)

    你点击“连接网盘”,在网盘登录页输入密码。网盘授权服务器给了“悦动音乐”两个字符串:

    • Access Token (AT):有效期 30 分钟。

    • Refresh Token (RT):有效期 30 天。

  • 第二步:畅听音乐(正常访问)

    前 30 分钟,App 每次点歌都带着 AT。网盘服务器说:“令牌有效,给你音频流”。

  • 第三步:令牌失效(尴尬瞬间)

    第 31 分钟,你点下一首歌。App 发送 AT,网盘服务器说:“这个令牌过期了,滚回去重来(401 错误)”。

  • 第四步:神奇的续命(刷新逻辑)

    App 此时并没有弹窗让你重新登录。App 的后台逻辑发现 AT 挂了,立刻掏出存了很久的 RT 发给网盘授权服务器:“嘿,我是‘悦动音乐’,这是我的 RT,之前的 AT 过期了,再给我开一个”。

  • 第五步:无感体验

    网盘服务器核对无误,发回一个新的 AT2。App 收到后,立刻用 AT2 去请求刚才那首歌。

    在你看来:你只是点了一下歌,音乐稍微延迟了 0.5 秒就开始播放了,完全不知道后台已经完成了一次“偷梁换柱”。


3. 为什么要有 Refresh Token?(安全考量)

你可能会问:为什么不直接把 Access Token 的有效期设为 30 天?

  1. 降低泄露风险:Access Token 在每次 API 请求中都在互联网上传输,非常容易被拦截。如果它有效期短,黑客即便偷到了,几分钟后也就失效了。

  2. 权限收回:Refresh Token 通常只发送给授权服务器(次数极少)。如果用户发现手机丢了,可以在网盘设置里点击“撤回授权”,授权服务器会把该 RT 作废。这样,即便黑客手里有 AT,只要它一过期,黑客就再也无法通过 RT 续期了。

在第五章的代码实现中,你会看到授权服务器需要额外增加一个判断逻辑:if (grant_type === 'refresh_token') { ... },并去数据库中验证这个长效字符串的有效性。