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

CSRF令牌验证失败:服务端Cookie 'csrftoken' 未定义导致403 Forbidden错误

CSRF令牌验证失败:服务端Cookie 'csrftoken' 未定义导致403 Forbidden错误

看起来你已经做了不少排查工作——日志都打了,也定位到了csrftoken Cookie在signup路由里是undefined的问题,这已经很关键了!我帮你梳理下核心问题点和对应的修复步骤:

核心问题诊断

你的double-csrf配置里,csrftoken是个带签名的HttpOnly Cookie,但服务端在signup时读不到它,直接导致令牌验证失败。这个Cookie本该由double-csrf的保护中间件自动生成,但显然中间件的挂载或者配置环节出了问题。

一步步修复方案

1. 先确认doubleCsrfProtection中间件被正确挂载

这个中间件是double-csrf的核心——它既要生成令牌、设置csrftoken Cookie,也要负责后续的验证。你必须把它挂载到所有需要CSRF支持的路由上,包括/csrf-token和/auth/signup:

// 要么全局挂载(所有路由都受保护/生成令牌)
app.use(doubleCsrfProtection);

// 要么给单个路由单独挂载
app.get('/csrf-token', doubleCsrfProtection, (req, res) => {
  // 你的现有代码
});

app.post('/auth/signup', doubleCsrfProtection, async (req, res) => {
  // 你的现有代码
});

如果没挂这个中间件,res.locals.csrfToken和csrftoken Cookie都不会生成,后续自然读不到。

2. 检查Cookie签名的配置(大概率是核心问题!)

你的csrftoken Cookie设置了signed: true,这意味着服务端必须用相同的签名密钥来解析它。如果你用了cookie-parser中间件,一定要传入和你CSRF配置一致的密钥:

const cookieParser = require('cookie-parser');
// 这里的密钥要和你double-csrf里的secret一致
app.use(cookieParser('CSRF_SECRET'));

要是没配置这个,服务端会把签名后的Cookie直接解析成undefined——这完全符合你日志里看到的现象!

3. 优化/csrf-token路由的令牌生成逻辑

你当前依赖res.locals.csrfToken,但如果中间件没正确生成,可以手动调用generateCsrfToken兜底,同时确保csrftoken Cookie被设置:

app.get('/csrf-token', doubleCsrfProtection, (req, res) => {
  let csrfToken = res.locals.csrfToken;
  // 兜底手动生成
  if (!csrfToken) {
    csrfToken = generateCsrfToken(req, res);
    if (!csrfToken) {
      console.error("Failed to generate CSRF token manually.");
      return res.status(500).json({ error: "Failed to generate CSRF token." });
    }
  }

  // 设置前端可读取的XSRF-TOKEN Cookie
  res.cookie('XSRF-TOKEN', csrfToken, { 
    httpOnly: false, 
    secure: process.env.NODE_ENV === 'production', 
    sameSite: 'lax' 
  });
  res.status(200).json({ csrfToken });
});

调用generateCsrfToken(req, res)会强制触发库设置csrftoken HttpOnly Cookie,解决生成环节的问题。

4. 确认会话标识的稳定性

你的getSessionIdentifier用了req.session.id,要确保express-session中间件配置正确,req.session确实存在且id是稳定的。可以在/csrf-token路由里加个日志确认:

console.log('当前会话ID:', req.session?.id);

如果会话ID是undefined或者每次请求都变,会导致CSRF令牌和会话绑定失败,同样会触发验证错误。

最后验证步骤

  1. 打开浏览器开发者工具的Application -> Cookies,检查csrftoken Cookie是否存在,属性是否符合配置(HttpOnly、路径/、SameSite=lax)
  2. 重新请求/csrf-token,看服务端日志有没有报错,前端能不能拿到令牌
  3. 发起signup请求时,确认X-CSRF-TOKEN请求头已经正确携带,同时csrftoken Cookie被浏览器自动带上

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:19:51