您好,登錄后才能下訂單哦!
前端請求token過期時(shí)刷新token的處理是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
在前端開發(fā)中,我們經(jīng)常會(huì)遇到使用token,token的作用是要驗(yàn)證用戶是否處于登錄狀態(tài),所以要請求一些只有登錄狀態(tài)才能查看的資源的時(shí)候,我們需要攜帶token。
一般的后端接口設(shè)置的token是有時(shí)效的,超時(shí)后就會(huì)失效,失效之后的處理策略一般會(huì)做兩種處理,一種是直接跳轉(zhuǎn)到登錄頁面,重新登錄。
流程圖如下:
另外一種如果返回 token失效的信息,自動(dòng)去刷新token,然后繼續(xù)完成未完成的請求操作。
流程圖如下:
但是此時(shí)我們要考慮一個(gè)問題,通常一個(gè)頁面中不只是發(fā)送一個(gè)異步請求,可能會(huì)同時(shí)發(fā)送多個(gè)異步請求,下面我們用流程圖來描述一下一個(gè)頁面同時(shí)發(fā)送多個(gè)請求的情況,并且者多個(gè)請求都需要驗(yàn)證token,圖示如下:
我們發(fā)現(xiàn),如果出現(xiàn)上述情況,token會(huì)被多次刷新,除了第一次判斷token失效后,進(jìn)行刷新token的操作,其余的刷新token都是多余的,我們應(yīng)該怎么處理呢?
首先咱們根據(jù)現(xiàn)實(shí)中的場景來模擬一下上面的獲取token與刷新token的動(dòng)作:
比如有5個(gè)人同時(shí)去買票,這里為了與是刷新token的場景類似,五個(gè)人從5個(gè)通道來買票,彼此并不知道還有其他四個(gè)人也來買票,這五個(gè)人都發(fā)現(xiàn)買票窗口沒人,此時(shí)按照剛才的場景,可能會(huì)出現(xiàn)如下情況,五個(gè)人,每個(gè)人都會(huì)去呼叫叫售票員,然后完成買票,還有一種情況是,其中某一個(gè)人去叫售票員,并且會(huì)在售票窗后貼一個(gè)紙條,告訴其他幾個(gè)人,售票員馬上來,其他四個(gè)人只需要等待即可。
第一種場景圖示如下:
這種場景會(huì)出現(xiàn)上面情況呢?可能會(huì)來五個(gè)售票員。。。
第二種場景圖示如下:
結(jié)合買票與刷新token的場景,我們再次觀察上面完成的偽代碼,我么需要如下幾個(gè)工具,紙條,觀察者。
紙條應(yīng)該是一個(gè)變量,其他用戶通過這個(gè)變量來判斷是否去刷新token,觀察者,當(dāng)售票員回來,或者token刷新完成,其他幾個(gè)用戶再次去完成業(yè)務(wù)邏輯。
最終的業(yè)務(wù)流程圖如下:
偽代碼實(shí)現(xiàn)如下:
const axios = require("axios");
// 封裝請求
function request(url, options) {
const token = localStorage.getItem('token');
const defaultOptions = {
headers: {
Authorization: `Bearer ${token}`,
},
withCredentials: true,
url: url,
baseURL: BASE_URL,
};
const newOptions = { ...options, ...defaultOptions };
return axios.request(newOptions)
.then(checkStatus)
.catch(error => console.log(error));
}
// 默認(rèn)紙條
let isRefreshing = true;
function checkStatus(response) {
if (response && response.code === 1002) {
// 刷新token的函數(shù),這需要添加一個(gè)開關(guān),防止重復(fù)請求
if(isRefreshing){
refreshTokenRequst()
}
isRefreshing = false;
// 將當(dāng)前的請求保存在觀察者數(shù)組中
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(()=> {
resolve(request(url, options))
})
});
return retryOriginalRequest;
}else{
return response;
}
}
function refreshTokenRequst(){
let data;
const refreshToken = localStorage.getItem('refreshToken');
data={
authorization: 'YXBwYXBpczpaSWxhQUVJdsferTeweERmR1praHk=',
refreshToken,
}
axios.request({
baseURL: BASE_URL,
url:'/app/renewal',
method: 'POST',
data,
}).then((response)=>{
// 刷新完成后,將刷新token和refreshToken存儲(chǔ)到本地
localStorage.setItem('refreshToken',response.data.refreshToken);
localStorage.setItem('token',response.data.token);
// 并且將所有存儲(chǔ)到觀察者數(shù)組中的請求重新執(zhí)行。
onAccessTokenFetched();
// 紙條撕掉
isRefreshing = true;
});
}
// 觀察者
let subscribers = [];
function onAccessTokenFetched() {
subscribers.forEach((callback)=>{
callback();
})
subscribers = [];
}
function addSubscriber(callback) {
subscribers.push(callback)
}
可以看到紙條相當(dāng)于變量isRefreshing,觀察者相當(dāng)于數(shù)組subscribers。以上便是token失效時(shí)的處理策略,如果你有其他想法歡迎留言。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。