You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React组件外的工具文件中获取Access Cookies实现Token刷新?

实现JWT自动刷新并在工具文件中获取Cookie的方案

方法一:直接使用浏览器原生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,直接在工具文件实例化:

  1. 安装依赖:
npm install universal-cookie
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:09:27