Day16 - 【概念篇】OAuth flows: Refresh Token

本系列文之後也会置於个人网站


  +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token

   The flow illustrated in Figure 2 includes the following steps:

   (A)  The client requests an access token by authenticating with the
        authorization server and presenting an authorization grant.

   (B)  The authorization server authenticates the client and validates
        the authorization grant, and if valid, issues an access token
        and a refresh token.

   (C)  The client makes a protected resource request to the resource
        server by presenting the access token.

   (D)  The resource server validates the access token, and if valid,
        serves the request.

   (E)  Steps (C) and (D) repeat until the access token expires.  If the
        client knows the access token expired, it skips to step (G);
        otherwise, it makes another protected resource request.

   (F)  Since the access token is invalid, the resource server returns
        an invalid token error.

使用refresh_token取得access_token

接着是使用Refresh Token换取Access Token的流程。这大概是所有中最简单的一个模式之一了。但因爲先决条件是取得可用的 Refresh Token ,所以无法单独存在。在RCF6749相关的流程图中,关注的是G、H的部分。至於一开始有什麽方式取得Refresh Token就非常的多。在已经介绍的密码模式和code模式都有可能返回refresh_token

如果你是直接从上一篇看下来的话,可能已经取得了refresh_token。但也许这个refresh_token已经过期了。爲此,将先在用密码模式取得一次access_tokenrefresh_token

同样使用RESTfer,针对flow-experiment-1这个Client取得refresh_token

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ4VXh6WGR4UWpFNDNIZGdYbXJkUjBQZWxXN1ZoZWowbGRkR2NhN0VubXpZIn0.eyJleHAiOjE2MzIwMjg1MzYsImlhdCI6MTYzMjAyODIzNiwianRpIjoiYjU5MWI5MDQtYzI3Ni00Mjc2LThmMDEtNGUzNTUwOTgzYTNmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3F1aWNrLXN0YXJ0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjM0NWIxYmNhLTk4MDUtNGI0Yi1hMGY4LWRhMmM3MDE3NmM1OSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImZsb3ctZXhwZXJpbWVudC0xIiwic2Vzc2lvbl9zdGF0ZSI6ImYxZjhkMzkyLTExZDAtNDEzMi05MDEwLTkyOGQ1NmFmMjM2MiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MjAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXF1aWNrLXN0YXJ0Iiwib2ZmbGluZV9hY2Nlc3MiLCJxdWljay1zdGFydC1leGFtcGxlLXJvbGUxIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiJmMWY4ZDM5Mi0xMWQwLTQxMzItOTAxMC05MjhkNTZhZjIzNjIiLCJ3ZWJzaXRlIjoiaHR0cHM6Ly9ib2IuaWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VuZGVyIjoibWFuIiwibmFtZSI6IkJvYiBMZWUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJib2IiLCJnaXZlbl9uYW1lIjoiQm9iIiwiZmFtaWx5X25hbWUiOiJMZWUiLCJlbWFpbCI6ImJvYkBmYWtlLmVtYWlsIn0.d5pTkQxoLteHVW_i_6iHSuTSYhJLyacoRr94HSM97E8txjn9kS55eG9dJIH0E8o0_02g9bR_YuLEStOo9xAgU42jiUsBvxNdeGjMkDyM5tPrtz7V9i_QTu_JUWpHpE5MFdChKAVOa7I5ldmQIEd97LfRINJaeXAu0x4lcmG5fhwBUuu-qR7O09S0D6tQT76wb2TpxqMsZxDprMxE2_CPMcfd7dAwzLdnCbz1iUyBPxdALSU5eY9AXo6uBsIHkDXfvVRj3QgrmXgIwBiv9WkHUet0lz9gwN-LBIOBTzAg9yO85keRXZwkWJRQ-87rWyp7bMZgS10Vrlv-hy-cT1qkDQ",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0NjUwNDBkYi1lNGJkLTRiYTYtOWM2Ny02ZWYxZGJmMmUxOWYifQ.eyJleHAiOjE2MzIwMzAwMzYsImlhdCI6MTYzMjAyODIzNiwianRpIjoiMmNlYTQwNzItMWE1Yi00M2I1LWE1M2YtY2Q3MDU0Mjg5NjY0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3F1aWNrLXN0YXJ0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL3F1aWNrLXN0YXJ0Iiwic3ViIjoiMzQ1YjFiY2EtOTgwNS00YjRiLWEwZjgtZGEyYzcwMTc2YzU5IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImZsb3ctZXhwZXJpbWVudC0xIiwic2Vzc2lvbl9zdGF0ZSI6ImYxZjhkMzkyLTExZDAtNDEzMi05MDEwLTkyOGQ1NmFmMjM2MiIsInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6ImYxZjhkMzkyLTExZDAtNDEzMi05MDEwLTkyOGQ1NmFmMjM2MiJ9.ThX7d498RX_9WuUq7_aEWx_Xrh75tyqpcrMCiVI3aMk",
    "token_type": "Bearer",
    "not-before-policy": 1631743594,
    "session_state": "f1f8d392-11d0-4132-9010-928d56af2362",
    "scope": "email profile"
}

接着将呼叫Web API的参数调整一下,改成:

  • grant_type: refresh_token
  • client_id: flow-experiment-1
  • refresh_token: <刚刚取得的refresh_token>

然後同样已POST的方法送出。这麽一来就可以取得新的存取权杖了,够简单吧!

refresh_token的作用

所以说爲什麽都可以透过密码模式、code模式取得存取权杖了,还需要refresh_token?首先先看看关於存取权杖的返回值:

其中是有expires_in的,也就是存取权杖会过期的。如果每次过期,都需要资源拥有者在登入一次是非常麻烦的。所以才有refresh_token,这同样类似 特殊密码 。与code模式的特殊密码有点不同的是,在限定时间内,可能可以透过refresh_token换取多次存取权杖。且与access_token不同的是,refresh_token使用在客户端与授权服务器;而access_token使用在客户端与资源服务器。相比access_tokenrefresh_token使用频率没那麽高,相对也就不容易被窃取,存活到过期时间通常也较长。藉由固定一段时间更新access_token的方式也可以降低一些安全隐患。

另外,refresh_token可以使用几次,使用多长时间。是否都会返回refresh_token,是由授权服务器决定的。也就是依照所需要的应用环境、所存在的安全风险,可能可以使用不同的策略。你可能频繁的更换access_tokenrefresh_token,也有可能一用就是一年。

参考资料


<<:  【设计+切版30天实作】|Day18 - Bootstrap的客制化

>>:  Day17-TypeScript(TS)的继承(Inheritance)

新新新手阅读 Angular 文件 - pathMatch(3) - Day29

本文内容 本文内容为阅读与 Angular 的 pathMatch:full 和 redirectT...

Day30 I’m on the next level

Summary 承续昨天所说,我们将PivotTable.js的版面调整,让资料区域的表格和图表可...

Day 26 -资料库应用小程序 设计程序介面

上一篇我们完成了资料库的建置,那麽我们现在就可以来处理如何应用啦! 开始实作 首先我们要先开启之前要...

D17/ 我要用的 View 没有支援 Compose 怎麽办? - AndroidView

今天大概会聊到的范围 Android View 前两天来回进出了公司楼下的 7-11 两三次,每次...

#1 地狱-序

前言 这是个四处充满数据的时代,大数据工程师已是一个不可或缺的职业,不仅科技产业都在招聘相关技术人员...