Axios拦截器问题:获取新Access Token后请求仍用旧令牌
Axios刷新Token后请求仍使用旧令牌的问题修复
问题描述
使用Axios时,遇到401未授权错误后成功获取了新的Access Token,但后续重试的请求仍然发送未更新的令牌,导致重复出现未授权错误。仅在刷新页面后,请求才会使用新的Token,请求截图显示两次请求携带的是同一个旧Token。
问题代码
import axios from 'axios' axios.defaults.baseURL='http://127.0.0.1:8000/api/' axios.defaults.headers.common['Content-Type']='application/json' let refresh = false axios.interceptors.response.use(res =>res ,async error =>{ if (error.response.status === 401 && !refresh ){ refresh=true const response= await axios.post('/user/refresh/',{},{withCredentials:true}) if(response.status===200){ axios.defaults.headers.common['Authorization']='JWT '+response.data.token return axios(error.config) } } refresh=false return error })
问题原因
当请求失败触发拦截器时,error.config中已经保存了旧的请求头信息(包括旧的Authorization Token)。即使更新了axios.defaults.headers.common['Authorization'],直接复用error.config发起重试请求时,依然会使用旧的请求头,不会自动同步全局默认配置里的新Token。
修复方案
在重试请求前,手动更新error.config中的Authorization头,确保重试请求携带新的Token:
import axios from 'axios' axios.defaults.baseURL='http://127.0.0.1:8000/api/' axios.defaults.headers.common['Content-Type']='application/json' let refresh = false axios.interceptors.response.use(res => res, async error => { if (error.response.status === 401 && !refresh) { refresh = true const response = await axios.post('/user/refresh/', {}, { withCredentials: true }) if (response.status === 200) { const newToken = 'JWT ' + response.data.token // 更新全局默认请求头 axios.defaults.headers.common['Authorization'] = newToken // 同时更新当前重试请求的config中的请求头 error.config.headers['Authorization'] = newToken return axios(error.config) } } refresh = false return error })
额外优化建议
- 添加刷新Token请求失败的处理逻辑,比如跳转至登录页面
- 可以完善请求队列机制,避免多个请求同时触发刷新Token的重复操作(当前的
refresh变量已做基础防重复,可根据业务需求进一步优化)
内容的提问来源于stack exchange,提问作者cryg0
相关产品推荐
相关产品推荐

