vue拦截器刷新登陆页面_vue下axios拦截器token刷新机制

本文介绍了如何在Vue应用中使用axios拦截器处理token过期问题。当检测到token过期时,通过刷新令牌接口更新token,并在成功后重新发起请求。同时,还展示了如何设置请求头、捕获错误并提示用户。
摘要由CSDN通过智能技术生成

//创建http.js文件,以下是具体代码:

//引入安装的axios插件

import axios from 'axios'import router from'@/router';

import Vue from'vue'const qs= require("qs");

let _this= newVue();

let isLock= false;

let refreshSubscribers=[];//判断token是否过期

functionisTokenExpired(token) {

let expires_time=JSON.parse(token).expires_time;

let curentTime= newDate().getTime();if (curentTime >=expires_time) {return true;

}else{return false;

}

}//获取Token对象

functiongetToken() {return localStorage.getItem("token");

}//push所有请求到数组中

functionsubscribeTokenRefresh(cb) {

refreshSubscribers.push(cb)

}//刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)

functiononRrefreshed(token) {

refreshSubscribers.map(cb=>cb(token))

}//刷新token

functionrefreshToken(config, token, resolve, reject) {

let data={ refresh_token: JSON.parse(token).refresh_token };

axios({

method:"post",

url:"xxxxxx/refreshToken",//刷新token的接口

headers: {"Content-Type": "application/x-www-form-urlencoded","Authorization": "Basic b3JkZXItc2VydmVyOjEyMzQ1Ng=="},

data: qs.stringify(data)

}).then(res=>{

isLock= false;//释放锁

if (res.data.code === 101) {

_this.$message.error('登录状态已失效,请重新登录。');

localStorage.removeItem("token");

router.push({

path:"/login"});return;

}

let expires_time= new Date().getTime() + parseInt(res.data.data.expires_in * 0.8) * 1000;

let token= JSON.parse(localStorage.getItem("token"));

token.expires_time=expires_time;

token.access_token=res.data.data.access_token;

localStorage.setItem("token", JSON.stringify(token));

config.headers.Authorization= 'Bearer ' +res.data.data.access_token;

resolve(config);//执行数组里的函数,重新发起被挂起的请求

onRrefreshed(res.data.data.access_token)//清空数组中保存的请求

refreshSubscribers =[]

}).catch(err =>{returnerr;

});

}functionrequest(newOptions, resolve, reject) {

axios({

method: newOptions.method,

url: newOptions.url,

data: newOptions.type== "form" ?qs.stringify(newOptions.data) : newOptions.data,

headers: newOptions.headers

}).then(res=>{if (res.status == 200) {//这里我们只需要获取返回的data中的数据即可

resolve(res.data);

}else{

reject(res.data);

}

}).catch(err =>{

reject(err);

_this.$message.error('服务异常!');

})

}

axios.interceptors.request.use(

config=>{

let token=getToken();if(token) {//判断token是否过期,如果过期请求刷新token

if(isTokenExpired(token)) {//判断当前是否正在请求刷新token

if (!isLock) {

isLock= true;//isLock设置true,锁住防止死循环。

//使用Promise等待刷新完成返回配置信息

let refresh = new Promise((resolve, reject) =>{

refreshToken(config, token, resolve, reject);

})returnrefresh;

}else{//判断当前url是否是刷新token的请求地址,如果是直接下一步。

if (config.url.indexOf('/logined/refreshToken') === -1) {//把请求(token)=>{....}都push到一个数组中

let retry = new Promise((resolve, reject) =>{//(token) => {...}这个函数就是回调函数

subscribeTokenRefresh((token) =>{

config.headers.Authorization= 'Bearer ' +token//将请求挂起

resolve(config)

})

})returnretry

}else{returnconfig;

}

}

}else{returnconfig;

}

}else{returnconfig;

}

}, error=>{returnPromise.reject(error);

});

const http= options =>{return new Promise((resolve, reject) =>{

const defaultOptions={

type:"json"};

const newOptions={

...defaultOptions,

...options

};//headers默认传递json格式数据,这里也可以设置token,每次调用都会携带if (localStorage.getItem("token")) {

newOptions.headers={//'Authorization': 'Basic b3JkZXItc2VydmVyOjEyMzQ1Ng==',

'content-Type': newOptions.type == 'form' ? 'application/x-www-form-urlencoded;charset=UTF-8' : 'application/json;charset=UTF-8','Authorization': 'Bearer ' + JSON.parse(localStorage.getItem("token")).access_token,

...newOptions.headers

};

}else{

newOptions.headers={'content-Type': newOptions.type == 'form' ? 'application/x-www-form-urlencoded;charset=UTF-8' : 'application/json;charset=UTF-8',

...newOptions.headers

};

}request(newOptions, resolve, reject);

})

};//设置请求超时

axios.defaults.timeout = 30000exportdefault http

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值