token刷新流程图
axios响应拦截器代码:
async function (error: AxiosError<{ message: string }>) {
// 如果没有response则网络问题
if (!error.response) {
return Toast.show({
icon: 'fail',
content: '网络错误!',
})
}
if (error.response.status === HttpStatusCode.Unauthorized) {
const { token, refresh_token } = store.getState().login
if (!token) {
// 没有token登录都没有登录 直接去登录
history.replace(`/login?redirect=${history.location.pathname}`)
Toast.show({
icon: 'fail',
content: '请先登录',
})
return Promise.reject(error)
}
try {
// 有token那就是过期了 刷新token 用新的axios实例发请求否则会继续走拦截器造成死循环401
const response = await axios<AxiosResponse<Token>>({
url: '/authorizations',
baseURL: 'http://www.xxx.com/',
method: 'PUT',
headers: {
Authorization: `Bearer ${refresh_token}`,
},
})
// 更新token到redux
store.dispatch({
type: 'auth/login',
payload: {
token: response.data.data.token,
refresh_token,
},
})
// 重新发起失败的请求
return request(error.config!)
} catch (error) {
// refresh_token失效导致无感刷新失败,直接去登录
history.replace(`/login?redirect=${history.location.pathname}`)
return Promise.reject(error)
}
}
Toast.show(error.response.data.message) // 打印兜底错误
return Promise.reject(error) // 每一个case都得return 否则使用相应结果的地方会访问undefined导致报错
}