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

Node Express中API端点CSRF错误规避问题:next()无法正常绕过

问题描述

我编写了一个中间件,原本用于在CSRF令牌无效时渲染404页面,同时想让REST_ENDPOINTS数组中的API端点绕过CSRF错误处理。但实际运行中,这些API端点仍持续弹出CSRF错误;若直接用next()跳过错误处理,仅对同域客户端请求有效,跨域API端点仍存在问题。我需要针对这些API端点禁用CSRF错误提示,但当前实现未达到预期效果。

相关代码

中间件代码

/*
* Middleware for rendering 404 page on invalid csrf token
*/
this.app.use((err: any, req: Request, res: Response, next: NextFunction) => {
    if (err.code === this.constants.CSRF.errCode) {
        let bypass = false;
        if (req.headers.referer || req.originalUrl || req.url) {
            let is_referer_url     = '';
            let is_originalUrl_url = '';
            let is_url             = '';
            // @ts-ignore
            is_referer_url         = req.headers.referer;
            is_url                 = req.url;
            is_originalUrl_url     = req.originalUrl;
            return REST_ENDPOINTS.forEach((endpoint) => {
                if (is_referer_url == endpoint
                    || is_originalUrl_url == endpoint
                    || is_url == endpoint) {
                    bypass = true;
                    return this.redirect(res, endpoint);
                }
            });
        }
        if (!bypass) {
            this.invalidCsrfResponse(req, res);
        }
        // this.invalidCsrfResponse(req, res);
        next()
    }
    if (err.code !== this.constants.CSRF.errCode)  {
        next(err);
    }
})

REST_ENDPOINTS数组

export const REST_ENDPOINTS = [
    "/get_example/",
    "/patch_example/",
    "/delete_example/"
]

简化后的绕过代码

this.app.use((err: any, req: Request, res: Response, next: NextFunction) => {
    if (err.code === this.constants.CSRF.errCode) {
        // this.invalidCsrfResponse(req, res);
        next()
    }
    if (err.code !== this.constants.CSRF.errCode)  {
        next(err);
    }
})

问题分析

  1. 原中间件逻辑错误:
    • 使用forEach遍历端点时,内部的return无法终止遍历,且会直接结束整个中间件函数,导致后续next()和bypass判断逻辑失效。
    • 错误地用referer(请求来源地址)匹配API端点,跨域请求的referer可能为空或不属于当前域名,根本无法匹配到目标端点;同时严格相等==匹配URL容易忽略路径参数、尾部斜杠等细节问题。
  2. 跨域处理不当:直接用next()跳过错误处理时,CSRF保护中间件可能仍在拦截跨域请求,且未针对API端点提前禁用CSRF验证。

解决方案

1. 提前对API端点禁用CSRF保护

在CSRF中间件生效前,先判断请求路径,对指定API端点跳过CSRF验证(以csurf中间件为例):

// 假设csrfMiddleware是你初始化的CSRF保护中间件
this.app.use((req, res, next) => {
  // 检查请求路径是否属于API端点列表
  const isApiRoute = REST_ENDPOINTS.some(endpoint => req.path === endpoint);
  if (isApiRoute) {
    return next(); // 跳过CSRF验证
  }
  // 非API路由应用CSRF保护
  csrfMiddleware(req, res, next);
});

2. 修正错误处理中间件逻辑

移除无效的referer判断,改用请求路径匹配,同时优化逻辑流程:

this.app.use((err: any, req: Request, res: Response, next: NextFunction) => {
  if (err.code === this.constants.CSRF.errCode) {
    // 验证当前请求是否为API端点
    const isApiEndpoint = REST_ENDPOINTS.some(endpoint => req.path === endpoint);
    if (isApiEndpoint) {
      return next(); // 跳过错误处理,继续执行后续逻辑
    }
    // 非API端点返回404页面
    this.invalidCsrfResponse(req, res);
    return; // 终止后续逻辑,避免重复调用next()
  }
  // 其他错误传递给下一个错误处理中间件
  next(err);
});

3. 配置正确的跨域规则

确保CORS配置允许目标跨域域名访问API端点,同时因为API端点无需CSRF保护,不需要传递CSRF令牌:

const corsOptions = {
  origin: "https://your-frontend-domain.com", // 替换为你的前端域名
  credentials: true, // 若需要携带Cookie则开启
};
// 注意:CORS中间件要放在CSRF和路由中间件之前
this.app.use(cors(corsOptions));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:45:42