RTK Query调用/refreshToken时如何替换Authorization头为refreshToken
实现方案(以Axios为例)
假设你使用Axios作为HTTP客户端,以下是具体实现逻辑:
1. 配置请求拦截器,支持跳过默认授权头
创建Axios实例时,添加请求拦截器,默认给请求带上Authorization: Bearer ${accessToken},但如果请求配置里带有skipAuthHeader: true标记,就跳过这个默认逻辑:
const api = axios.create({ baseURL: '/api' }); // 请求拦截器:默认设置accessToken授权头,标记跳过则不处理 api.interceptors.request.use(config => { if (!config.skipAuthHeader && localStorage.getItem('accessToken')) { config.headers.Authorization = `Bearer ${localStorage.getItem('accessToken')}`; } return config; });
2. 响应拦截器捕获403,触发Token刷新流程
在响应拦截器里捕获403状态码,判断是accessToken过期导致的(可结合后端返回的错误标识,比如errorCode: 'TOKEN_EXPIRED'),然后发起刷新请求:
// 响应拦截器处理403刷新Token逻辑 api.interceptors.response.use( response => response, async error => { const originalRequest = error.config; // 过滤掉刷新Token的请求本身,且标记未重试过,避免循环请求 if (error.response.status === 403 && !originalRequest._retry && originalRequest.url !== '/refreshToken') { originalRequest._retry = true; try { // 发起refreshToken请求:跳过默认授权头,手动用refreshToken设置请求头 const refreshRes = await api.post('/refreshToken', {}, { skipAuthHeader: true, // 跳过默认的accessToken授权逻辑 headers: { Authorization: `Bearer ${localStorage.getItem('refreshToken')}` // 手动传入refreshToken } }); // 更新本地存储的新accessToken const newAccessToken = refreshRes.data.accessToken; localStorage.setItem('accessToken', newAccessToken); // 重新发起原请求,带上新的accessToken originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; return api(originalRequest); } catch (refreshErr) { // 刷新失败(比如refreshToken也过期),直接跳转到登录页 window.location.href = '/login'; return Promise.reject(refreshErr); } } return Promise.reject(error); } );
核心细节说明
- 跳过默认授权逻辑:通过自定义
skipAuthHeader标记,让请求拦截器自动跳过默认的accessToken设置,确保refresh请求能手动使用refreshToken。 - 防止循环请求:给原始请求添加
_retry标记,避免刷新Token失败后再次触发403拦截,陷入无限循环。 - 手动指定refresh请求头:在调用
/refreshToken时,直接在请求配置的headers里设置授权信息,确保用的是refreshToken而非默认的accessToken。
如果使用其他HTTP客户端(如Fetch、Axios之外的库),核心逻辑一致:
- 给请求添加标记区分是否需要跳过默认授权
- 响应拦截捕获403后,发起带refreshToken的请求(跳过默认授权)
- 更新accessToken后重试原请求
内容的提问来源于stack exchange,提问作者shawnMarkus
相关产品推荐
相关产品推荐

