【SSO單點登入】JWT續簽問題 && OAuth2.0 中的refreshToken重新整理機制

語言: CN / TW / HK

theme: smartblue highlight: solarized-light


持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第 5 天,點選檢視活動詳情

大家好,我是melo,一名大三後臺練習生,不知不覺練習時間長達一年了!!!

👉本篇速覽

  • JWT續簽問題

    • 快過期時返回新的token
    • refreshToken

      • 如何判斷refreshToken的有效性
      • 擴充套件 -- OAuth2.0 中的refreshToken重新整理機制
    • 其他需要重新整理token的情況

      • 使用者修改了角色許可權
      • 刪除了某個身份角色

為什麼需要續簽

如果給JWT設定了一個有效時間的話,時間到JWT是會過期的。但假如這個時候使用者正在提交重要資訊,填了一大堆資訊,按下按鈕時,後臺攔截器發現token過期,告知前端,前端直接退回登入頁,那這次提交就相當於無效了,還得登入後重新填一遍【當然前端也能做快取,這裡就不考慮那麼多了,只是個栗子】

而原始JWT設計下,是沒有考慮續簽問題的。所以續簽(即延長JWT的過期時間)工作需要我們自己來做。

快過期了返回新的token

類似於 Session 認證中的做法: 假設服務端給的 token 有效期設定為30分鐘,服務端每次進行校驗時,如果發現 token 的有效期馬上快過期了, 服務端就重新生成 token 給客戶端。

客戶端每次請求都檢查新舊token,如果不一致,則更新客戶端儲存的token。 - 這種做法的問題是僅僅在快過期的時候請求才會更新 token ,對客戶端不是很友好。

refreshToken重新整理機制

流程圖

使用者登入返回兩個 token :第一個是 acessToken ,它的過期時間比較短,比如是1天;另外一個是 refreshToken 它的過期時間更長一點,可以是accessToken的2倍:2天。

客戶端登入後,將 accessToken和refreshToken 儲存在客戶端本地,每次訪問將 accessToken 傳給服務端。服務端校驗 accessToken 的有效性,

如果過期的話,就將 refreshToken 傳給服務端。如果 refreshToken 有效,服務端就生成新的 accessToken 給客戶端。否則,客戶端就重新登入即可。

🎆如何判斷refreshToken的有效性

將生成的 Refresh Token 以及過期時間儲存在服務端的資料庫中,由於 Refresh Token 不會在客戶端請求業務介面時驗證,只有在申請新的 Access Token 時才會驗證,所以將 Refresh Token 儲存在資料庫中,不會對業務介面的響應時間造成影響,也不需要像 Session 一樣一直保持在記憶體中以應對大量的請求。

當然,更安全的方式是,客戶端需要繫結一個client_id和secret,服務端會驗證這個refreshToken是否是改客戶端發起的,防止被盜用【這個是後話了,我們後續基於token的SSO單點登入,驗證令牌ticket的時候還會著重講解】

缺點

  • 重新請求獲取 token 的過程中會有短暫 token 不可用的情況(可以通過在客戶端設定定時器,當accessToken 快過期的時候,提前去通過 refreshToken 獲取新的accessToken)。

擴充套件 -- OAuth2.0中的重新整理機制

客戶端在獲得access token的同時也會在響應資訊中得到一個名為expires_in的資料,它表示當前獲得的access token會在多少秒以後過期。 當超過該指定的秒數後,access token便會過期。當access token過期後,如果客戶端依然用它訪問服務,服務端就會返回invalid_token的錯誤或401錯誤碼。 ```java HTTP/1.1 401 Unauthorized Content-Type: application/json Cache-Control: no-store Pragma: no-cache

{ "error": "invaild_token" } ```

如果使用者訪問的時候,客戶端的"訪問令牌AccessToken"已經過期,則需要使用"更新令牌refreshToken"申請一個新的訪問令牌。

客戶端發出更新令牌的HTTP請求,包含以下引數:

  • granttype:表示使用的授權模式,此處的值固定為"refreshtoken",必選項。
  • refresh_token:表示早前收到的更新令牌,必選項。
  • scope:表示申請的授權範圍,不可以超出上一次申請的範圍,如果省略該引數,則表示與上一次一致。

```java POST /v1/oauth2/token HTTP/1.1 Host: melo.com Authorization: Bearer zskldjflsdjflksjdflkjsd Content-Type: application/x-www-form-urlencoded

grent_type=refresh_token&refresh_tokne=ajsldkjflskdfjldfg ```

其他需要重新整理token的情況

使用者修改了角色的許可權

由於許可權是在登入的時候,繫結在token裡邊了,若登入後,管理員修改了角色的許可權,而服務端此時還拿一開始登入的token去獲取許可權的話,就會出現不同步,所以需要主動重新整理token更新許可權

刪除了某個身份角色

情況跟上邊是類似的,本質上也是身份許可權發生了變更,只要是token中的資訊,發生了變化,而我們之後還要用到,會出現資料不一致的情況,就需要重新整理token

💠下篇預告

  • 本篇就JWT續簽問題和OAuth2.0展開了解讀,也算是淺提及到了OAuth2.0機制,後續的SSO單點登入基於ticket形式實現,其中就借鑑了OAuth2.0中的授權碼機制。
  • 聊完了前置知識,Cookie和Session以及JWT,下篇我們將正式進入SSO單點登入篇,展開第一種SSO單點登入方式--基於Cookie和Session實現,敬請期待~

🧿友鏈