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

Node.js多层架构下验证请求来源:确保请求来自自有前端的方案

验证请求来自自有前端的解决方案

针对你这种三层架构下中间层Node.js服务器需要验证请求来源的问题,我整理了几个实用且成熟的方案,结合你的场景给出具体实现思路:

1. Origin/Referer 请求头校验

这是最基础的防御手段,利用浏览器的同源策略特性:

  • 原理:浏览器发送跨域请求时会自动带上Origin头(简单请求)或Referer头(跳转/部分请求),标识请求的发起页面域名。
  • 实现步骤:
    • 在Node.js中间层中,检查请求的Origin或Referer是否属于你的前端域名白名单(比如https://your-frontend.com,开发环境可加入本地调试地址)。
    • 示例代码(Express框架):
      const allowedOrigins = ['https://your-frontend.com', 'http://localhost:3000'];
      app.use((req, res, next) => {
        // 优先取Origin,没有则从Referer中解析域名
        const origin = req.headers.origin || 
                      (req.headers.referer ? `${req.headers.referer.split('/')[0]}//${req.headers.referer.split('/')[2]}` : '');
        if (allowedOrigins.includes(origin)) {
          next();
        } else {
          res.status(403).send('Forbidden: Invalid request origin');
        }
      });
      
  • 注意:这种方式容易被手动伪造请求头,所以不能单独作为唯一防御手段,需要配合其他方案。

2. CSRF Token 验证

适合表单提交类请求,是Web应用防御跨站请求伪造的标准方案:

  • 原理:前端页面加载时从中间层获取唯一CSRF Token,提交请求时将Token放在请求头或表单隐藏字段中,中间层校验Token与用户Session中的值是否一致。
  • 实现步骤:
    1. 前端加载页面时,向中间层请求CSRF Token(比如GET /api/csrf-token),中间层生成Token并存储在用户Session中(需设置HttpOnly: false让前端能读取)。
    2. 前端提交表单/XHR请求时,将Token放在X-CSRF-Token请求头中。
    3. 中间层校验请求头中的Token与Session中的Token是否匹配。
  • 示例代码(Express + express-session):
    const crypto = require('crypto');
    // 生成CSRF Token接口
    app.get('/api/csrf-token', (req, res) => {
      req.session.csrfToken = crypto.randomBytes(16).toString('hex');
      res.send({ csrfToken: req.session.csrfToken });
    });
    
    // CSRF校验中间件
    app.use((req, res, next) => {
      // 仅对修改类请求校验
      if (['POST', 'PUT', 'DELETE'].includes(req.method)) {
        const requestCsrfToken = req.headers['x-csrf-token'];
        if (requestCsrfToken === req.session.csrfToken) {
          next();
        } else {
          res.status(403).send('Forbidden: Invalid CSRF Token');
        }
      } else {
        next();
      }
    });
    
  • 优势:Token与用户Session绑定,伪造难度大,完美适配你的表单提交场景。

3. 请求签名验证

适合更严格的场景,即使请求头被伪造也能有效验证:

  • 原理:前端和中间层共享一个保密密钥,前端发送请求时,用密钥对请求关键参数(请求路径、时间戳、用户ID等)进行哈希签名,中间层用相同规则验证签名有效性。
  • 实现步骤:
    1. 前端通过安全接口动态获取共享密钥(禁止硬编码在前端代码中,密钥需定期轮换)。
    2. 发送请求时,生成签名:将请求路径 + 时间戳 + 用户ID拼接后,用HMAC-SHA256算法和密钥生成签名,把签名和时间戳放在X-Signature、X-Timestamp请求头中。
    3. 中间层先校验时间戳是否在有效范围(比如5分钟内,防止重放攻击),再生成预期签名与请求头中的签名对比。
  • 示例代码(Node.js中间层):
    const crypto = require('crypto');
    const sharedSecret = 'your-rotating-shared-secret'; // 与前端共享的密钥,注意保密和定期轮换
    
    app.use((req, res, next) => {
      const signature = req.headers['x-signature'];
      const timestamp = req.headers['x-timestamp'];
      const path = req.path;
      const userId = req.session.userId; // 结合用户登录态提升安全性
    
      // 校验请求是否过期
      if (Date.now() - parseInt(timestamp) > 5 * 60 * 1000) {
        return res.status(403).send('Forbidden: Request expired');
      }
    
      // 生成预期签名
      const payload = `${path}${timestamp}${userId}`;
      const expectedSignature = crypto.createHmac('sha256', sharedSecret)
                                    .update(payload)
                                    .digest('hex');
    
      if (signature === expectedSignature) {
        next();
      } else {
        res.status(403).send('Forbidden: Invalid request signature');
      }
    });
    

综合建议

  • 对于你的表单提交场景,优先使用CSRF Token + Origin校验的组合,简单易实现且安全性足够。
  • 如果需要更高的安全等级,再加入请求签名验证,防止请求被重放或伪造。
  • 永远不要依赖单一防御手段,多层验证能大幅提升系统安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:13:12