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

Express生成的CSRF Token在Postman中有效但React中无效如何解决

排查思路及解决方案

核心问题定位

你遇到的问题90%以上是因为获取CSRF Token的请求没有配置withCredentials: true,导致浏览器没有保存Express下发的存储CSRF Secret的Cookie,后续请求提交的Token和服务端存储的Secret匹配不上。


分步排查

1. 验证CSRF Cookie下发逻辑

打开浏览器调试工具「应用」面板,找到Express服务端域名对应的Cookie存储,确认是否有名为_csrf的Cookie:

  • 不存在:说明/auth/csrf请求未携带凭证,需要给这个GET请求单独加withCredentials配置,修改后的代码如下:
export const getCSRFToken = async () => {
  try {
    // 这里必须加withCredentials,否则浏览器会拒收跨域Cookie
    const { data } = await axios.get("/auth/csrf", { withCredentials: true });
    // 不要只给POST请求加头,PUT/DELETE等请求也需要,直接挂到通用头
    axios.defaults.headers.common["X-CSRF-Token"] = data.csrfToken;
  } catch (error) {
    console.error("CSRF Token获取失败", error);
  }
};
  • 存在:继续往下排查

2. 验证请求头携带逻辑

打开浏览器调试工具「网络」面板,查看报错的业务请求:

  • 确认请求头中存在X-CSRF-Token字段,值和/auth/csrf接口返回的一致
  • 确认请求方法匹配:如果业务请求用的是PUT/DELETE等非POST方法,只给axios.defaults.headers.post加头会导致头缺失,改为挂到common通用头即可解决

3. 验证服务端配置

  • 确认中间件加载顺序:业务路由必须注册在csrfProtection中间件之后,否则中间件不会校验路由请求
  • 跨域场景适配:如果前后端域名/端口差异较大,可以调整CSRF Cookie配置适配跨域:
const csrfProtection = csrf({
  cookie: {
    httpOnly: true,
    sameSite: 'lax', // 跨站测试可以临时改为'none',需配合secure: true(仅HTTPS可用)
    // domain: '.yourdomain.com' 线上同根域名场景可配置扩大Cookie作用域
  },
});

4. 验证Token时效性

不要只在应用初始化时调用一次getCSRFToken,如果服务端_csrf Cookie过期或刷新,已存储的Token会直接失效,建议增加两种适配逻辑:

  • 每次路由切换前重新拉取一次Token
  • 在axios响应拦截器中监听invalid csrf token错误,自动重拉Token后重试原请求

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:06:03