https://datatracker.ietf.org/doc/html/rfc6749#section-1.5 https://datatracker.ietf.org/doc/html/rfc6749#section-6
1. 为什么会有 Refresh Token
1.1 为什么 ACCESS_TOKEN
要设计有效期
再之前的文章中, 介绍了4中许可类型, 每个流程最终的目的是获取一个 ACCESS_TOKEN
;
拥有这个 ACCESS_TOKEN
则拥有了一定的权限, 那么对于用户来说, 权限是自己的, 肯定不希望权限被滥用 ;
由于ACCESS_TOKEN
是每一次请求都会被使用, 所以被窃取的风险会更大一些, 那么最简单有效的做法就是给 ACCESS_TOKEN
一个过期时间,
即使ACCESS_TOKEN
被泄露, 那么过了有效期权限也就收回了, 也能有效地止损
但是 ACCESS_TOKEN
加了有效期, 就会导致 Client 频繁的去走各种许可类型的流程;
如果这个流程需要用户进行交互, 则会导致用户Resource Owner
的体验较差, 频繁的要去进行授权
1.2 如何解决 ACCESS_TOKEN
过期导致的 重新授权问题呢?
如果在 获取ACCESS_TOKEN
的时候, 一并给Client一个REFRESH_TOKEN
当 ACCESS_TOKEN
失效的时候, 使用 REFRESH_TOKEN
重新获取一个新的 ACCESS_TOKEN
则就不需要用户Resource Owner
的参与, 用户的体验就更好了
而这个 REFRESH_TOKEN
在平时是不会被使用了, 所以较难被窃取
1.3 什么时候提供REFRESH_TOKEN
?
四种许可类型中, 获取ACCESS_TOKEN
这一步基本可以认为是安全性最高的一步了
所以我在给 ACCESS_TOKEN
的时候 一并将REFRESH_TOKEN
给 client
2. 流程图
- Client获取授权
- AuthServer返回
access_token
和refresh_token
- Client使用
access_token
获取受保护的资源 - ResourceServer返回受保护的资源
- 当Client请求受保护的资源时, 返回了token失效
- Client则拿着
refresh_token
请求AuthServer, 换取最新的access_token
- AuthServer返回最新的
access_token
和 新的refresh_token
3. 改造支持 refresh_token
3.1 AuthServer改造
- 新增通过
REFRESH_TOKEN
获取 (ACCESS_TOKEN
和新的REFRESH_TOKEN
) 的接口 - 资源服务在
ACCESS_TOKEN
过期的时候返回Invalid Token Error
错误 - Client在获取
ACCESS_TOKEN
的时候, 将REFRESH_TOKEN
一并返回
示例:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
3.2 Cilent改造
- 在获取
ACCESS_TOKEN
的同时要将REFRESH_TOKEN
一并保存下来, 最好持久化下来 - 新增通过
REFRESH_TOKEN
刷新 的功能 - 改造请求受保护资源的错误校验, 当遇到
Invalid Token Error
的时候, 调用REFRESH_TOKEN
刷新功能
4. refresh请求
示例
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA