如何在React组件外的工具文件中获取Access Cookies实现Token刷新?
方法一:直接使用浏览器原生document.cookie解析
无需依赖react-cookie,直接在工具文件里读取并解析Cookie:
- 编写Cookie解析工具函数:
// utils/cookieUtils.js export const getCookie = (name) => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); };
- 在axios实例中集成刷新逻辑:
// utils/axiosInstance.js import axios from 'axios'; import { getCookie } from './cookieUtils'; const axiosInstance = axios.create({ baseURL: process.env.REACT_APP_API_URL, }); axiosInstance.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config; // 判断Token过期且未重试过 if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; const refreshToken = getCookie('refreshToken'); if (refreshToken) { try { // 调用刷新Token接口 const { data } = await axios.post('/api/auth/refresh', { refreshToken }); // 更新请求头中的Access Token originalRequest.headers.Authorization = `Bearer ${data.accessToken}`; // 更新Cookie中的Access Token(按需) document.cookie = `accessToken=${data.accessToken}; path=/; max-age=3600`; // 重新发起原始请求 return axiosInstance(originalRequest); } catch (refreshError) { // 刷新失败,跳转登录页 window.location.href = '/login'; return Promise.reject(refreshError); } } else { // 无Refresh Token,直接跳转登录 window.location.href = '/login'; return Promise.reject(error); } } return Promise.reject(error); } ); export default axiosInstance;
方法二:使用universal-cookie库(兼容多环境)
如果项目需要服务端渲染(SSR),或想更优雅处理Cookie,可使用universal-cookie,它无需hooks,直接在工具文件实例化:
- 安装依赖:
npm install universal-cookie
- 在axios实例中集成:
// utils/axiosInstance.js import axios from 'axios'; import Cookies from 'universal-cookie'; const cookies = new Cookies(); const axiosInstance = axios.create({ baseURL: process.env.REACT_APP_API_URL, }); axiosInstance.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; const refreshToken = cookies.get('refreshToken'); if (refreshToken) { try { const { data } = await axios.post('/api/auth/refresh', { refreshToken }); originalRequest.headers.Authorization = `Bearer ${data.accessToken}`; // 更新Cookie cookies.set('accessToken', data.accessToken, { path: '/', maxAge: 3600 }); return axiosInstance(originalRequest); } catch (refreshError) { window.location.href = '/login'; return Promise.reject(refreshError); } } else { window.location.href = '/login'; return Promise.reject(error); } } return Promise.reject(error); } ); export default axiosInstance;
关键注意事项
- 若Refresh Token设置了
httpOnly属性(推荐用于安全),前端无法通过JS读取,此时需后端配合:刷新接口直接从Cookie中获取Refresh Token,前端仅需发起刷新请求即可。 - 处理并发请求:当多个请求同时触发Token过期时,需用Promise锁保证仅发起一次刷新请求,避免重复调用刷新接口。
内容的提问来源于stack exchange,提问作者Jake Mulhern
相关产品推荐
相关产品推荐

