当token失效后,需要使用refresh_token去刷新请求新的token,当刷新完请求之后,要将同一时间因为token失效而请求失败的请求再次发送。
思路:定义一个isRefreshing = false标志,当刷新请求时 isRefreshing = true
定义一个储存刷新token期间返回的401接口的数组,requestList = [],当刷新token后重新发起这些失败的请求。
const request = axios.create({
baseURL: '',
timeout: 10000
})
// 请求拦截器
request.interceptors.request.use(
config => {
// 统一设置用户身份 Token
const token = 'xxx'
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
error => {
return Promise.reject(error)
}
)
// 控制刷新token的状态
let isRereshing = false
// 存储刷新token期间过来的401请求
let requestList: any[] = []
// 响应拦截器
request.interceptors.response.use(
response => {
const { code, result, message } = response.data
// 状态为2xx都会进入
if (code === ResultEnum.SUCCESS) {
return result
} else {
// 做其他错误响应
ElMessage.error(`错误信息: ${message as string}`)
return Promise.reject(response.data)
}
},
async (err) => {
// 超出2状态码的进入这里
if (err.response) {
// 请求发出并收到响应
const { status } = err.response
if (status === 400) {
ElMessage.error('请求参数错误')
} else if (status === 401) {
// 判断是否登录,没有登录的401直接返回到登录页面
const usertore = useUserStore()
if (!usertore.userInfo.id) {
redirectLogin()
return Promise.reject(err)
}
// 已登录, token过期 刷新token
if (!isRereshing) {
isRereshing = true
return axios.post(url,{ refreshToken: usertore.userInfo?.refreshToken ?? '' }).then(res => {
if (res.data.code !== '0000') {
throw new Error('刷新 Token 失败')
}
// 刷新成功
usertore.userInfo.token = res.data.data.token
usertore.userInfo.refreshToken = res.data.data.refreskToken
requestList.forEach(cb => cb())
requestList = []
return request(err.config)
}).catch(e => {
usertore.userInfo = {
id: '',
userName: '',
roleId: '',
roleName: ''
}
redirectLogin()
return Promise.reject(e)
}).finally(() => {
isRereshing = false
})
}
// 正在刷新中
return new Promise(resolve => {
requestList.push(() => {
resolve(request(err.config))
})
})
} else if (status === 403) {
ElMessage.error('没有权限,请联系管理员')
} else if (status === 404) {
ElMessage.error('请求的资源不存在')
} else if (status > 500) {
ElMessage.error('服务端错误,请联系管理员')
} else {
ElMessage.error('请求失败')
}
} else if (err.request) {
ElMessage.error('请求超时,请刷新重试')
} else {
ElMessage.error('请求失败')
}
return Promise.reject(err)
}
)