vue下axios拦截器token刷新机制
程序员文章站
2022-05-28 14:12:11
//创建http.js文件,以下是具体代码://引入安装的axios插件 import axios from 'axios' import router from '@/router'; import Vue from 'vue' const qs = require("qs"); let _thi ......
//创建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遇到的问题,现在分享给大家,如果对你有帮助记得留言,谢谢!!
上一篇: 位运算的简单应用-权限管理
下一篇: HTML5页面架构元素 - 标签