// 导入 vuex 模块
import store from '@/store/index.js'
// 导入路由模块
// 导入 router 模块
import router from '@/router/index.js'
console.log(store)
// 这是请求地址
const root = 'http://127.0.0.1:8000' // 请求根路径
// 创建 axios 的实例对象,并共享出去
const request = axios.create({
// 请求的根路径
baseURL: 'http://127.0.0.1:8000'
baseURL: root
})
// 1. 拦截器的挂载,一定要放到 request 实例创建之后
request.interceptors.response.use(
Toast.clear()
return response
},
function(error) {
async function(error) {
// 对响应错误做点什么
// 隐藏 loading 效果
Toast.clear()
// 判断一下失败的 status 状态码是否为 401。
// 如果是 401 证明是 token 过期导致的有权限的接口调用失败!
if (error.response.status === 401) {
// 证明 Token 过期了
// 1. 强制跳转到登录页
router.replace('/login')
// 2. 清空 vuex 和 localStorage 中的数据
store.commit('cleanState')
// 从 vuex 中获取 refresh_token 的值
const refreshToken = store.state.tokenInfo.refresh_token
// 如果 refresh_token 有值,且响应状态码为 401,则应该执行换取 token 的操作
if (error.response.status === 401 && refreshToken) {
console.log('换取 token 的操作')
try {
// 大坑1:千万不要在这里直接使用 request 对象,来发起换取 Token 的请求
const { data: res } = await axios({
method: 'PUT',
// 大坑2:直接使用 axios 发起请求的时候,必须给定完整的 URL 地址,因为 axios 没有配置 baseURL
url: root + '/v1_0/authorizations',
headers: {
// 大坑3:Authorization 的值格式必须为 Bearer xxx
Authorization: 'Bearer ' + refreshToken
}
})
console.log('token 换取成功!')
console.log(res)
// TODO1:用新 token 替换到 vuex 和 localStorage 中的旧 token
store.commit('updateTokenInfo', { token: res.data.token, refresh_token: refreshToken })
// TODO2:继续完成上次失败的那个请求
return request(error.config)
} catch {
// 只要能够执行到 catch 中的代码,证明 token 和 refresh_token 都过期了
store.commit('cleanState')
// 强制用户跳转到登录页
router.replace('/login?pre=' + router.currentRoute.fullPath)
}
}
return Promise.reject(error)
vue 项目实现无痛刷新token保持登录状态
最新推荐文章于 2024-08-11 14:56:15 发布