vue下axios拦截器token刷新机制


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



//
引入安装的axios插件 import axios from 'axios' import router from '@/router'; import Vue from 'vue' const qs = require("qs"); let _this = new Vue(); let isLock = false; let refreshSubscribers = []; //判断token是否过期 function isTokenExpired(token) { let expires_time = JSON.parse(token).expires_time; let curentTime = new Date().getTime(); if (curentTime >= expires_time) { return true; } else { return false; } } //获取Token对象 function getToken() { return localStorage.getItem("token"); } //push所有请求到数组中 function subscribeTokenRefresh(cb) { refreshSubscribers.push(cb) } //刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据) function onRrefreshed(token) { refreshSubscribers.map(cb => cb(token)) } //刷新token function refreshToken(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 => { return err; }); } function request(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); }) return refresh; } 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) }) }) return retry } else { return config; } } } else { return config; } } else { return config; } }, error => { return Promise.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 = 30000 export default http
//在main.js下面挂载 http.js文件
import http from '@/utils/http.js';
Vue.prototype.http = http;
//登录保存token信息接口

this.http({
            method: "post",
            url: "/xxxxx/user",
            type: "form",
            headers: { Authorization:"Basicb3JkZXItc2VydmVyOjEyMzQ1Ng==" },
            data: {}
          }).then(function(res) {
               let expires_time =
                  new Date().getTime() +
                  parseInt(res.data.token.expires_in * 0.8) * 1000;
                  let token = res.data.token;
                  token.expires_time = expires_time;
                localStorage.setItem("token", JSON.stringify(token));
        
            }).catch(function(err) {
              console.log(err);
            });                
//退出清空token
this.http({
        method: "get",
        url: "/xxxxx/logout",
        data: {}
      }).then(function(res) {
 localStorage.removeItem("token");
    }).catch(function(err) {
          console.log(err);
        });

这是本人做自动刷新token遇到的问题,现在分享给大家,如果对你有帮助记得留言,谢谢!!

猜你喜欢

转载自www.cnblogs.com/cxf1992/p/12205074.html