Refresh Token(刷新令牌)详解
在第五章中,刷新令牌(Refresh Token) 的引入是为了解决“安全”与“用户体验”之间的矛盾。访问令牌(Access Token)通常有效期很短(如 1 小时),如果过期后要用户重新登录,体验会很糟糕。刷新令牌则允许客户端在后台偷偷“续期”。
以下是它的业务逻辑和具体案例:
1. 刷新令牌的业务逻辑流程
刷新令牌的逻辑主要分为 “获取” 和 “使用” 两个阶段:
阶段一:获取(伴随访问令牌一起发放)
-
用户授权:用户同意授权后,客户端拿着授权码(Code)去授权服务器换令牌。
-
双证齐发:授权服务器验证通过,返回一个 JSON 包,里面不仅有
access_token,还有一个refresh_token。 -
持久化存储:客户端将
access_token存入临时缓存,将refresh_token安全地存入数据库(因为它的有效期通常很长,几天甚至几个月)。
阶段二:使用(访问令牌过期时)
-
请求失败:客户端拿着
access_token请求资源服务器,收到401 Unauthorized错误。 -
后台静默续期:客户端不再跳转到登录页,而是直接向授权服务器的 令牌端点 发起 POST 请求:
-
参数包含:
grant_type=refresh_token和refresh_token=xxxx。 -
同时需要提供客户端的身份证明(Client ID 和 Secret)。
-
-
验证并翻新:授权服务器检查
refresh_token是否有效、是否被撤回。验证通过后,颁发一个新的access_token(有时也会滚动更新refresh_token)。 -
重试请求:客户端拿到新令牌,重新发起之前失败的 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 天?
-
降低泄露风险:Access Token 在每次 API 请求中都在互联网上传输,非常容易被拦截。如果它有效期短,黑客即便偷到了,几分钟后也就失效了。
-
权限收回:Refresh Token 通常只发送给授权服务器(次数极少)。如果用户发现手机丢了,可以在网盘设置里点击“撤回授权”,授权服务器会把该
RT作废。这样,即便黑客手里有AT,只要它一过期,黑客就再也无法通过RT续期了。
在第五章的代码实现中,你会看到授权服务器需要额外增加一个判断逻辑:if (grant_type === 'refresh_token') { ... },并去数据库中验证这个长效字符串的有效性。