前端请求token过期时刷新token的处理是怎样的
前端请求token过期时刷新token的处理是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
在前端开发中,我们经常会遇到使用token,token的作用是要验证用户是否处于登录状态,所以要请求一些只有登录状态才能查看的资源的时候,我们需要携带token。
一般的后端接口设置的token是有时效的,超时后就会失效,失效之后的处理策略一般会做两种处理,一种是直接跳转到登录页面,重新登录。
流程图如下:
另外一种如果返回 token失效的信息,自动去刷新token,然后继续完成未完成的请求操作。
流程图如下:
但是此时我们要考虑一个问题,通常一个页面中不只是发送一个异步请求,可能会同时发送多个异步请求,下面我们用流程图来描述一下一个页面同时发送多个请求的情况,并且者多个请求都需要验证token,图示如下:
我们发现,如果出现上述情况,token会被多次刷新,除了第一次判断token失效后,进行刷新token的操作,其余的刷新token都是多余的,我们应该怎么处理呢?
首先咱们根据现实中的场景来模拟一下上面的获取token与刷新token的动作:
比如有5个人同时去买票,这里为了与是刷新token的场景类似,五个人从5个通道来买票,彼此并不知道还有其他四个人也来买票,这五个人都发现买票窗口没人,此时按照刚才的场景,可能会出现如下情况,五个人,每个人都会去呼叫叫售票员,然后完成买票,还有一种情况是,其中某一个人去叫售票员,并且会在售票窗后贴一个纸条,告诉其他几个人,售票员马上来,其他四个人只需要等待即可。
第一种场景图示如下:
这种场景会出现上面情况呢?可能会来五个售票员。。。
第二种场景图示如下:
结合买票与刷新token的场景,我们再次观察上面完成的伪代码,我么需要如下几个工具,纸条,观察者。
纸条应该是一个变量,其他用户通过这个变量来判断是否去刷新token,观察者,当售票员回来,或者token刷新完成,其他几个用户再次去完成业务逻辑。
最终的业务流程图如下:
伪代码实现如下:
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));
}
// 默认纸条
let isRefreshing = true;
function checkStatus(response) {
if (response && response.code === 1002) {
// 刷新token的函数,这需要添加一个开关,防止重复请求
if(isRefreshing){
refreshTokenRequst()
}
isRefreshing = false;
// 将当前的请求保存在观察者数组中
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存储到本地
localStorage.setItem('refreshToken',response.data.refreshToken);
localStorage.setItem('token',response.data.token);
// 并且将所有存储到观察者数组中的请求重新执行。
onAccessTokenFetched();
// 纸条撕掉
isRefreshing = true;
});
}
// 观察者
let subscribers = [];
function onAccessTokenFetched() {
subscribers.forEach((callback)=>{
callback();
})
subscribers = [];
}
function addSubscriber(callback) {
subscribers.push(callback)
}
可以看到纸条相当于变量isRefreshing,观察者相当于数组subscribers。以上便是token失效时的处理策略,如果你有其他想法欢迎留言。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。