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. 流程图

image.png

  1. Client获取授权
  2. AuthServer返回access_tokenrefresh_token
  3. Client使用access_token获取受保护的资源
  4. ResourceServer返回受保护的资源
  5. 当Client请求受保护的资源时, 返回了token失效
  6. Client则拿着 refresh_token请求AuthServer, 换取最新的access_token
  7. AuthServer返回最新的access_token和 新的refresh_token

3. 改造支持 refresh_token

3.1 AuthServer改造

  1. 新增通过REFRESH_TOKEN获取 (ACCESS_TOKEN和新的 REFRESH_TOKEN) 的接口
  2. 资源服务在 ACCESS_TOKEN过期的时候返回 Invalid Token Error错误
  3. Client在获取ACCESS_TOKEN的时候, 将REFRESH_TOKEN一并返回

示例:

  1. HTTP/1.1 200 OK
  2. Content-Type: application/json;charset=UTF-8
  3. Cache-Control: no-store
  4. Pragma: no-cache
  5. {
  6. "access_token":"2YotnFZFEjr1zCsicMWpAA",
  7. "token_type":"example",
  8. "expires_in":3600,
  9. "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  10. "example_parameter":"example_value"
  11. }

3.2 Cilent改造

  1. 在获取ACCESS_TOKEN的同时要将 REFRESH_TOKEN一并保存下来, 最好持久化下来
  2. 新增通过 REFRESH_TOKEN刷新 的功能
  3. 改造请求受保护资源的错误校验, 当遇到 Invalid Token Error的时候, 调用 REFRESH_TOKEN 刷新功能

4. refresh请求

参见: https://datatracker.ietf.org/doc/html/rfc6749#section-6

示例

  1. POST /token HTTP/1.1
  2. Host: server.example.com
  3. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
  4. Content-Type: application/x-www-form-urlencoded
  5. grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA