檔案名稱 | 版本号 | 作者 | 版本 | |
---|---|---|---|---|
OAuth2.0重新整理Token | v1.0.0 | 學生宮布 | 8416837 | SpringBoot 2.2.6 SpringCloud Hoxton.SR4 |
文章目錄
-
-
- 需求
- 假設你已經搭建好OAuth2.0伺服器
- 解決辦法
-
- 1)定時器
- 2)請求攔截式,每次請求權限接口都判斷是否可以重新整理Token了
-
需求
- 保證頁面不會在正在操作中卻彈出Token過期,這樣體驗不好。除非好久(設定的門檻值)沒有操作頁面了,顯示已過期才合理。
假設你已經搭建好OAuth2.0伺服器
- 登入(授權)成功後,響應資料長這個樣子:
OAuth2.0重新整理Token,正在操作時,Token不過期
名詞 | 釋義 | 備注 |
---|---|---|
access_token | 作為消費服務的通行證,逾期會失效 | |
refresh_token | 用來換取新的access_token,會失效,但一般應該設定比access_token晚些失效 | |
expires_in | 多久過期(秒) | 可在資料庫設定或者在令牌管理器代碼設定 |
- 但如果正在操作中,令牌(通行證)突然到期失效了,那多尴尬
- 是以需要在即将過期或已經過期的時候,重新整理Token。——前提是refresh_token沒有過期且合法。
解決辦法
- 前提:可以成功擷取Token,并成功在用戶端維護Token、過期時間
1)定時器
- 原理 計算Token過期的時間點,開始計時,當目前時間點接近過期點的時候,執行重新整理Token操作。要保證每個頁面都可能觸發計時器,且隻能有一個,當頁面重新整理時,計時器不受影響。
- 代碼 節選
// 從存儲擷取過期時間
computed: mapGetters(['userInfo', 'isLock', 'isCollapse', 'website', 'expires_in']),
... ...
// 這裡是aJax請求攔截器
// 如果即将過期,則調用重新整理API,參數是refresh_token, grant_type:授權類型,即refresh_token, scope;并鎖住重新整理接口
if (this.expires_in <= 1000 && !this.refreshLock) {
this.refreshLock = true
this.$store
.dispatch('RefreshToken')
.catch(() => {
clearInterval(this.refreshTime)
});
this.refreshLock = false
}
// expires_in遞減
this.$store.commit("SET_EXPIRES_IN", this.expires_in - 10);
... ...
this.$store.dispatch('RefreshToken')
:調用重新整理 API
2)請求攔截式,每次請求權限接口都判斷是否可以重新整理Token了
- 代碼 節選
// 這裡是aJax請求攔截器
window.isRefreshing = false
... ...
// futureTime:Token在将來某個時間點過期
if (!window.isRefreshing && futureTime && (futureTime - new Date().getTime() ) <= EXPIRED_IN_THIS_SECONDS ) { // 如果expires_in_time eq 0,則很可能是初次登陸,進而勿須重新整理令牌 假如設定還差6秒過期
// 鎖 避免多個調用重複重新整理
window.isRefreshing = true
// 重新整理Token
如果同時調用多個接口,而此時Token已經過期,但refresh_token沒有過期的話,最先重新整理的接口可以執行成功,另外的接口不會重新整理,會導緻請求失敗。但是之後會正常,因為已經重新整理了。見下圖:
文章目錄
-
-
- 需求
- 假設你已經搭建好OAuth2.0伺服器
- 解決辦法
-
- 1)定時器
- 2)請求攔截式,每次請求權限接口都判斷是否可以重新整理Token了
-