vue axios实现双token无感刷新
vue实现token无感刷新
·
流程
1.首先,登录得到了两个token,并将其存起来
2.当access_token过期时,自动发送refresh_token到刷新token的请求路径请求token刷新
3.得到新的token之后,将请求重新发送,实现用户无感刷新token
代码
主要在响应拦截中,进行token的无感刷新
import axios from 'axios'
import {Message} from 'element-ui'
import router from '../router/index'
import store from '@/store'
import { getToken, getFreshToken } from '@/utils/auth'
import Api from '@/api/login'
// 超时设定
axios.defaults.timeout = 200000
// 请求拦截器
axios.interceptors.request.use(config => {
const hasToken = store.getters['user/token']
if (hasToken) {
config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
}, err => {
Message.error('系统繁忙,请稍候再试。')
return Promise.resolve(err)
})
// 响应拦截器
//标志当前是否正在刷洗token
let isNotRefreshing = true;
//请求队列
let requests = [];
axios.interceptors.response.use((response) => {
const data = response
const status = data.data.code
const config = response.config;
let text = ''
switch (status) {
case '4030':
// 刷新token
if (getFreshToken() != null) {
if (isNotRefreshing) {
isNotRefreshing = false;
return Api.refreshToken({refresh_token: getFreshToken()}).then(res => {
if (res.data.code != '200') {
window.sessionStorage.clear()
window.localStorage.clear()
if(document.getElementsByClassName('el-message').length < 1){
Message({
showClose: true,
message: res.data.message,
type: 'warning'
})
}
router.push({
path: '/login'
})
return false
} else {
window.sessionStorage.setItem('FRESH ', res.data.data.refresh_token)
window.sessionStorage.setItem('Bearer ', res.data.data.access_token)
//执行requests队列中的请求,(requests中存的不是请求参数,而是请求的Promise函数,这里直接拿来执行就好)
requests.forEach(run => run())
//将请求队列置空
requests = []
//重新执行当前未执行成功的请求并返回
return axios(config);
}
}).catch(() => {
window.sessionStorage.clear()
window.localStorage.clear()
router.push({
path: '/login'
})
})
.finally(() => {
isNotRefreshing = true;
})
}else{
return new Promise(resolve => {
//这里加入的是一个promise的解析函数,将响应的config配置对应解析的请求函数存到requests中,等到刷新token回调后再执行
requests.push(() => {
resolve(axios(config));
})
})
}
}else{
if(document.getElementsByClassName('el-message').length < 1){
Message({
showClose: true,
message: '请重新登录!',
type: 'warning'
})
}
window.sessionStorage.clear()
window.localStorage.clear()
router.push({
path: '/login'
})
}
break
case '402':
text = '您已超时,请重新登录。'
if(document.getElementsByClassName('el-message').length < 1){
Message({
showClose: true,
message: text,
type: 'warning'
})
}
window.sessionStorage.clear()
window.localStorage.clear()
router.push({
path: '/login'
})
break
}
return data
}, (error) => {
// 返回状态码不为200时候的错误处理
var reg = /[^0-9]/ig
const errorContent = JSON.parse(JSON.stringify(error)).message
const status = errorContent.replace(reg, '')
let text = ''
switch (status) {
case '402':
// 请求接口
Message({
showClose: true,
message: '由于您长时间没有操作,请您重新登录',
type: 'warning'
})
// window.sessionStorage.clear()
// window.localStorage.clear()
// window.location.href = '/login'
break
case '403':
break
case '500':
text = '服务器开小差了,请稍后再试'
Message({
showClose: true,
message: text,
type: 'warning'
})
break
case '404':
text = '网络异常,请重试'
Message({
showClose: true,
message: text,
type: 'warning'
})
break
default:
// text = '服务器开小差了'
// Message({
// showClose: true,
// message: text,
// type: 'warning'
// })
}
})
参考网址:
更多推荐
已为社区贡献2条内容
所有评论(0)