前端如何實現 token 的無感刷新

大家都知道,用戶初次打開客戶端時,只是一介平民,毫無身份特權可言。 

當用戶將正確的賬號以及密碼,呈遞給服務端進行檢驗,待檢驗成功之後,服務器端便會親手打造一個名爲 Token 的令牌,並給予客戶端。

客戶端自此便擁有了身份,也擁有了符合身份的資源請求權限…… 

但,Token 是有時間限制的!關於時間的設置不宜過長,這樣不夠安全。更不宜過短,這樣會讓用戶頻繁登陸,遭受吐槽!

那有沒有什麼比較好的解決方案?有,通過無感刷新 token!即 token 在更新時用戶無感知,從而避免用戶的頻繁登陸。

關於無感刷新網上一般有三種解決方案:

1、後端返回過期時間,前端判斷 token 過期時間, 去調用刷新 token 接口。缺點:需要後端額外提供一個 Token 過期時間的字段;使用了本地時間判斷,若本地時間篡改,特別是本地時間比服務器時間慢時,攔截會失敗。

2、寫個定時器,定時刷新 Token 接口。缺點:浪費資源, 消耗性能, 不建議採用。

3、在響應攔截器中攔截,判斷 Token 返回過期後,調用刷新 token 接口。

以上三種解決方案都是建立在前端調用後端刷新 Token 接口的基本之上的。雖然可以解決 Token 的時間設置問題,但是無形中又增加了前端代碼的冗餘量。比如:請求時需要增加中間變量防止多次刷新 token;同時發起兩個或者兩個以上的請求時,需要藉助 Promise 安排 Token 刷新接口的調用順序。

其實 Token 也是需要設計的,只要設計的合理,也可大大減少後續的煩惱:

後端在創建 Token 時,可以將時間設置爲 Token 生成時間,請求過期時間,刷新 token 過期時間,以及總體過期時間 (根據項目需求而定)。四個時間的關係:

請求時間是否在總體過期時間內,如果不在則告知前端 Token 異常,並讓用戶重新登陸。如果在則判斷請求時間是否過期。

請求時間一旦過期,查看時間是否在刷新 token 的允許時間內,如果在則重新生成 token 並響應給前端,前端更新 Token。如果不在則告知前端 Token 異常,並讓用戶重新登陸。

後端實現:略

前端大體實現:

import axios from 'axios';
axios.interceptors.response.use(response => {
        // token異常
        if (response.data.code === 409) {
            removeToken();// 刪除token
            router.push('/login');
            return Promise.reject("token異常");
        } else if (response.data.code === 410) {// 服務端Token更新
            const {token} = res.data
            setToken(token);// 重置token
        }
        return response && response.data
    }
)

    以上是個人對開發中使用 Token 的一點總結,如有敘述不當之處請指正,我將及時改正並感謝!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/41TvLj4jxdgMNBWE3bIN5g