js⽆痛刷新Token的实现
这个需求场景很常见,⼏乎很多项⽬都会⽤上,之前项⽬也实现过,最近刚好有个项⽬要实现,重新梳理⼀番。需求
对于需要前端实现⽆痛刷新Token,⽆⾮就两种:
请求前判断Token是否过期,过期则刷新
请求后根据返回状态判断是否过期,过期则刷新
处理逻辑
实现起来也没多⼤差别,只是判断的位置不⼀样,核⼼原理都⼀样:
判断Token是否过期
没过期则正常处理
过期则发起刷新Token的请求
拿到新的Token保存
重新发送Token过期这段时间内发起的请求
重点:
保持Token过期这段时间发起请求状态(不能进⼊失败回调)
把刷新Token后重新发送请求的响应数据返回到对应的调⽤者
实现
创建⼀个flag isRefreshing来判断是否刷新中
创建⼀个数组队列retryRequests来保存需要重新发起的请求
判断到Token过期isRefreshing = false的情况下发起刷新Token的请求
刷新Token后遍历执⾏队列retryRequests
isRefreshing = true表⽰正在刷新Token,返回⼀个Pending状态的Promise,并把请求信息保存到队列retryRequests中import axios from "axios";
import Store from "@/store";
import Router from "@/router";
import { Message } from "element-ui";
import UserUtil from "@/utils/user";
// 创建实例
const Instance = ate();
Instance.defaults.baseURL = "/api";
Instance.defaults.headers.post["Content-Type"] = "application/json";
Instance.defaults.headers.post["Accept"] = "application/json";
// 定义⼀个flag 判断是否刷新Token中
let isRefreshing = false;
// 保存需要重新发起请求的队列
let retryRequests = [];
// 请求拦截
quest.use(async function(config) {
Storemit("startLoading");
const userInfo = LocalInfo();
if (userInfo) {
//业务需要把Token信息放在 params ⾥⾯,⼀般来说都是放在 headers⾥⾯
config.params = Object.assign(config.params ? config.params : {}, {
appkey: userInfo.AppKey,
token: userInfo.Token
});
}
return config;
});
// 响应拦截
sponse.use(
async function(response) {
Storemit("finishLoading");
const res = response.data;
if (de == 0) {
solve(res);
} else if (
) {
// 需要刷新Token 的状态 30001 40001 42001 40014
// 拿到本次请求的配置
let config = fig;
//  进⼊登录页⾯的不做刷新Token 处理
if (Router.currentRoute.path !== "/login") {
if (!isRefreshing) {
/
/ 改变flag状态,表⽰正在刷新Token中
isRefreshing = true;
//  刷新Token
return Store.dispatch("user/relogin")
.then(res => {
// 设置刷新后的Token
ken = res.Token;
config.params.appkey = res.AppKey;
//  遍历执⾏需要重新发起请求的队列
retryRequests.forEach(cb => cb(res));
//  清空队列
retryRequests = [];
quest(config);
js assign})
.catch(() => {
retryRequests = [];
<("⾃动登录失败,请重新登录");
const code = Store.state.user.info.CustomerCode || "";
// 刷新Token 失败清空缓存的⽤户信息并调整到登录页⾯
Store.dispatch("user/logout");
path: "/login",
query: { redirect: Router.currentRoute.fullPath, code: code }
});
})
.finally(() => {
// 请求完成后重置flag
isRefreshing = false;
});
} else {
// 正在刷新token,返回⼀个未执⾏resolve的promise
// 把promise 的resolve 保存到队列的回调⾥⾯,等待刷新Token后调⽤
// 原调⽤者会处于等待状态直到队列重新发起请求,再把响应返回,以达到⽤户⽆感知的⽬的(⽆痛刷新)          return new Promise(resolve => {
// 将resolve放进队列,⽤⼀个函数形式来保存,等token刷新后直接执⾏
retryRequests.push(info => {
// 将新的Token重新赋值
ken = info.Token;
config.params.appkey = info.AppKey;
quest(config));
});
});
}
}
return new Promise(() => {});
} else {
ject(res);
}
},
function(error) {
let err = {};
if (sponse) {
} else {
}
Storemit("finishLoading");
ject(err);
}
);
export default Instance;
到此这篇关于js⽆痛刷新Token的实现的⽂章就介绍到这了,更多相关js⽆痛刷新Token内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。