问题引入
用户在做一些操作时,可能由于token过期而导致用户需要重新登录才能进行后面的操作。这是为了接口数据的安全考虑,后端会对token设置一个过期时长,而token过期的话用户就需要重新的登录才能操作特殊的操作,会对用户不太友好。这时就需要使用无痛(无感)刷新了。
实现思路:
在响应拦截器中根据过期token调用登录刷新token值。
实现代码:
//将需要携带token的请求存放进数组中
const METHOD_TYPE = ["_mt=edit","_mt=create","_mt=delete"];
//添加响应拦截器
instance.interceptors.response.use(async function(response){
let data = response.data
let {errmsg,errno} = data;//解构出我们所需要的数据
if(10006===errno){
//获取接口请求数据
let configData = response.config.data || "";//获取登录时的请求方法和参数
//请求类型是否为无痛刷新 index !== -1需要刷新令牌
var index = METHOD_TYPE.findIndex(item=>configData.includes(item));
if(-1 === index){//需要重新登录获取令牌
router.replace({
path:"/logins",//跳转到登陆页面
query:{back:path}//登录之后回到跳转前的页面,优化用户体验
})
return;
}else{
let store = useUserstore();//这是是使用pinia如不使用可以替换成临时存储或永久存储
let {username,password} = store.loginInfo;
//重新获取令牌
let loginData = {_gp: "admin",_mt: "login",username,password}
let {errno,errmsg,data} = await post(loginData);//同步请求
if(200==errno){
jsCookie.set("token",data);//保存令牌到cookie
}else{
router.replace({
path:"/logins",
query:{back:path}//登录之后需要跳回地址,优化用户体验
})
return Promise.reject({errno,errmsg,data});
}
//重新发送上次的请求
return instance.request(response.config)
}
}
return data;
},function(error){
return Promise.reject(error)
})