1.登录成功后,拿到vueX里的token(本地也存储过),给请求都添加token
vueX里的tokenInfo包括token和refresh_token
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// token 在 user模块里
const token = store.state.user.tokenInfo.token
/* 如果token存在的话,给每个请求加上token */
if (token) {
config.headers.Authorization = Bearer ${token}
}
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 处理token
/*
- 有refresh_token,用refresh_token去请求回新的token
- 新token请求成功
- 更新本地token
- 再发一次请求A
- 新token请求失败
- 清空vuex中的token
- 携带请求地址,跳转到登陆页
- 新token请求成功
- 没有refresh_token
- 清空vuex中的token
- 携带请求地址,跳转到登陆页 */
request.interceptors.response.use(function (response) {
// 对响应数据做点什么 (成功响应) response 就是成功的响应 res
return response
}, async function (error) {
// 对响应错误做点什么 (失败响应) 处理401错误
// console.dir(error)
if (error.response.status === 401) {
// 获取 refresh_token, 判断是否存在, 存在就去刷新token
const refreshToken = store.state.user.tokenInfo.refresh_token
if (refreshToken) {
try {
// 获取新的token
const res = await axios({
method: 'put',
url: 'http://toutiao-app.itheima.net/v1_0/authorizations',
// 请求头中携带refresh_token信息
headers: {
Authorization:Bearer ${refreshToken}
}
})
const newToken = res.data.data.token
// 将新token更新到vuex中
store.commit('user/setTokenInfo', {
refresh_token: refreshToken,
token: newToken
})
// 重新发送页面请求, 携带的是token
return request(error.config)
} catch (error) {
// 说明, 有refresh_token, 但是refresh_token也失效了 (登录失效了)
// 先清除无效的token (vuex)
store.commit('user/removeTokenInfo')
Toast.fail('登录已过期, 请重新登录')
router.push({
path: '/login',
query: {
backTo: router.currentRoute.fullPath
}
})
}
} else {
// 没有refreshToken, 直接去登录, 将来还能跳回来
// router.currentRoute 指向当前路由信息对象 === 等价于之前页面中用的 this.$route
// 清除本地token, 跳转登录 (无意义的本地token内容, 要清除)
store.commit('removeToken')
router.push({
path: '/login',
query: {
// currentRoute当前路由
backto: router.currentRoute.fullPath
}
})
}
}
// 对响应错误做点什么
// return new Promise(function (resolve, reject) {
// reject(error)
return Promise.reject(error)
})