溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

前端請求token過期時(shí)刷新token的處理是怎樣的

發(fā)布時(shí)間:2021-12-23 16:43:51 來源:億速云 閱讀:863 作者:柒染 欄目:大數(shù)據(jù)

前端請求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過期時(shí)刷新token的處理是怎樣的

另外一種如果返回 token失效的信息,自動(dòng)去刷新token,然后繼續(xù)完成未完成的請求操作。

流程圖如下:

前端請求token過期時(shí)刷新token的處理是怎樣的

但是此時(shí)我們要考慮一個(gè)問題,通常一個(gè)頁面中不只是發(fā)送一個(gè)異步請求,可能會(huì)同時(shí)發(fā)送多個(gè)異步請求,下面我們用流程圖來描述一下一個(gè)頁面同時(shí)發(fā)送多個(gè)請求的情況,并且者多個(gè)請求都需要驗(yàn)證token,圖示如下:

前端請求token過期時(shí)刷新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è)人只需要等待即可。

第一種場景圖示如下:

前端請求token過期時(shí)刷新token的處理是怎樣的

這種場景會(huì)出現(xiàn)上面情況呢?可能會(huì)來五個(gè)售票員。。。

第二種場景圖示如下:

前端請求token過期時(shí)刷新token的處理是怎樣的

結(jié)合買票與刷新token的場景,我們再次觀察上面完成的偽代碼,我么需要如下幾個(gè)工具,紙條,觀察者。

紙條應(yīng)該是一個(gè)變量,其他用戶通過這個(gè)變量來判斷是否去刷新token,觀察者,當(dāng)售票員回來,或者token刷新完成,其他幾個(gè)用戶再次去完成業(yè)務(wù)邏輯。

最終的業(yè)務(wù)流程圖如下:

前端請求token過期時(shí)刷新token的處理是怎樣的

偽代碼實(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è)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(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)容。

AI