vue拦截器增加token参数
使用请求拦截器,拦截vue所有请求,增加token参数
使用倒数计时,假如token有效期60分钟,会在59分钟的时候去重新拿着refresh_Token,去请求新的token.
注意
如果一个账号允许多人登录使用,上述方法没有问题
但是如果一个账号只允许一人登录,一个地点登录,那上述方法就不那么全面
这时候可以采用使用响应拦截器,拦截状态码进行对应的异常处理
然后判断哪些是token失效,再进行对应的登出操作或者是重新获取token
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | import axios from 'axios' import { getToken } from '@/utils/auth' import { getToken_refresh } from '@/api/users' import router from '../router/index' ; // 创建axios实例 const service = axios.create({ // baseURL: 'http://127.0.0.1:8081/auth', timeout: 10000 // 请求超时时间 }) /*是否有请求正在刷新token*/ window.isRefreshing = false /*被挂起的请求数组*/ let refreshSubscribers = [] /*获取刷新token请求的token*/ function getRefreshToken () { return localStorage.getItem( "refresh_token" ) } /*push所有请求到数组中*/ function subscribeTokenRefresh (cb) { refreshSubscribers.push(cb) } /*刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)*/ function onRrefreshed (token) { refreshSubscribers.map(cb => cb(token)) } // request 请求拦截器 service.interceptors.request.use(config => { if (getToken()) { config.params[ 'access_token' ] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 /*判断token是否将要过期*/ var istoken = isTokenExpired(); if (istoken) { /*判断是否正在刷新*/ if (!window.isRefreshing) { /*将刷新token的标志置为true*/ window.isRefreshing = true /*发起刷新token的请求*/ var params = { refresh_token: localStorage.getItem( 'refresh_Token' ), }; getToken_refresh(params).then((res) => { /*将标志置为false*/ window.isRefreshing = false /*成功刷新token*/ // config.headers.Authorization = res.data.data.token_type + ' ' + res.data.data.token /*更新auth*/ if (res.data.code == 0){ alert( "登录超时,请重新登录" ); router.push({ path: '/login' }) return } localStorage.setItem( 'Token' ,res.data.data.access_token); localStorage.setItem( 'refresh_Token' ,res.data.data.refresh_token); localStorage.setItem( "expired_at" ,res.data.data.expired_at); config.params[ 'access_token' ] = getToken() /*执行数组里的函数,重新发起被挂起的请求*/ onRrefreshed(res.data.data.access_token) /*执行onRefreshed函数后清空数组中保存的请求*/ refreshSubscribers = [] }). catch (err => { alert(err.response.data.message) /*清除本地保存的auth*/ // localStorage.removeItem('auth') window.location.href = '#/login' }) } /*把请求(token)=>{....}都push到一个数组中*/ let retry = new Promise((resolve, reject) => { /*(token) => {...}这个函数就是回调函数*/ subscribeTokenRefresh((token) => { // config.headers.Authorization = 'Bearer ' + token config.params[ 'access_token' ] = token /*将请求挂起*/ resolve(config) }) }) return retry } } else { router.push({ path: '/login' }) } return config }, error => { // Do something with request error console.log( "11111" +error) // for debug Promise.reject(error) }) // response 响应拦截器 service.interceptors.response.use( response => { // console.log(response) if (response.status !== 200) { if (response.status === 500) { // 服务器断开 this .$message({ showClose: true , message: '服务器断开,请稍后重试。' , type: 'error' }); } return Promise.reject( new Error(response.message || 'Error' )) } else { return response } },error => { // console.log("cesc"+error) if (error.response.status === 401) { // token失效 ,重新获取token var params = { refresh_token: localStorage.getItem( 'refresh_Token' ), }; getToken_refresh(params).then((res) => { /*更新auth*/ if (res.data.code == 0){ alert( "登录超时,请重新登录" ); router.push({ path: '/login' }) return } localStorage.setItem( 'Token' ,res.data.data.access_token); localStorage.setItem( 'refresh_Token' ,res.data.data.refresh_token); localStorage.setItem( "expired_at" ,res.data.data.expired_at); }). catch (err => { alert(err.response.data.message) /*清除本地保存的auth*/ // localStorage.removeItem('auth') window.location.href = '#/login' }) } else if (error.response.status === 500) { // 服务器断开 alert( "服务器断开,请稍后重试。" ); } else if (error.response.status === 403){ //无auth授权,后台不允许访问 alert( "不允许访问,请与技术人员联系" ); } return response return Promise.reject(error) } ) /*判断token是否过期*/ function isTokenExpired() { let expiredTime = new Date().getTime() / 1000; /*从localStorage中取出token过期时间*/ if (localStorage.getItem( "expired_at" ) != undefined && localStorage.getItem( "expired_at" ) != "undefined" ){ expiredTime = new Date(localStorage.getItem( "expired_at" )).getTime() / 1000 } /*获取本地时间*/ let nowTime = new Date().getTime() / 1000 /*如果 |
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。