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

MERN应用如何防止他人通过开发者工具篡改POST请求负载?

解决方案:加固请求防篡改与校验机制

首先明确:不存在100%可靠的方法能区分控制台发送的请求和应用正常发送的请求——控制台完全可以模拟应用请求的所有头信息、参数。所以核心思路是从请求体防篡改和权限校验入手,彻底堵死篡改的可能。

1. 对敏感请求体参数添加签名校验

给敏感参数生成签名,客户端发送请求时同时带上签名,服务端重新计算签名并比对,不一致则拒绝请求。

实现步骤:

  • 前端:在发送包含敏感参数的POST请求前,用一个仅前后端约定的密钥(存在环境变量,避免暴露给用户),对敏感参数(或整个请求体)进行哈希签名(比如HMAC-SHA256)。
  • 后端:接收请求后,用相同的密钥和算法重新计算签名,和前端传来的签名比对,不一致则直接返回403。

代码示例:

前端(React):

import crypto from 'crypto-js';

const secretKey = process.env.REACT_APP_SIGNATURE_KEY;

// 生成请求体签名
function generateSignature(payload) {
  return crypto.HmacSHA256(JSON.stringify(payload), secretKey).toString();
}

// 发送带签名的请求
async function sendProtectedRequest(payload) {
  const signature = generateSignature(payload);
  const response = await fetch('/api/protected-endpoint', {
    method: 'POST',
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
      'X-Request-Signature': signature
    },
    body: JSON.stringify(payload)
  });
  return response.json();
}

后端(Express):

const crypto = require('crypto');

const secretKey = process.env.SIGNATURE_KEY;

// 签名校验中间件
function validateSignature(req, res, next) {
  const clientSignature = req.headers['x-request-signature'];
  if (!clientSignature) {
    return res.status(403).json({ message: '缺少签名验证' });
  }

  const payloadStr = JSON.stringify(req.body);
  const serverSignature = crypto
    .createHmac('sha256', secretKey)
    .update(payloadStr)
    .digest('hex');

  if (clientSignature !== serverSignature) {
    return res.status(403).json({ message: '请求体已被篡改' });
  }
  next();
}

// 给敏感接口挂载校验中间件
app.post('/api/protected-endpoint', validateSignature, (req, res) => {
  res.json({ success: true });
});

2. 完善服务端参数校验逻辑

对所有应由代码生成、用户不可修改的参数,做严格校验:

  • 枚举类参数,直接判断是否在允许的列表内;
  • 用户关联参数,校验是否与当前登录用户的ID匹配;
  • 数值/字符串参数,校验范围、长度、格式规则。

示例:

app.post('/api/user/create-post', (req, res) => {
  const { postType, content, userId } = req.body;
  const currentUserId = req.user.id; // 从JWT解析当前登录用户ID

  // 校验文章类型是否合法
  const allowedTypes = ['article', 'note', 'image'];
  if (!allowedTypes.includes(postType)) {
    return res.status(400).json({ message: '无效的文章类型' });
  }

  // 校验用户ID是否与当前登录用户一致
  if (userId !== currentUserId) {
    return res.status(403).json({ message: '无权操作该用户资源' });
  }

  // 处理请求逻辑...
});

3. 限制请求频率(防暴力篡改尝试)

用express-rate-limit中间件对敏感接口设置请求频率限制,防止用户反复尝试篡改参数:

const rateLimit = require('express-rate-limit');

const protectedApiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 10, // 每个IP最多10次请求
  message: { message: '请求过于频繁,请稍后再试' }
});

app.post('/api/protected-endpoint', protectedApiLimiter, validateSignature, (req, res) => {
  // 处理请求
});

4. 避免前端传递敏感参数(从服务端直接生成)

如果某个参数完全不需要用户输入、仅由代码生成,干脆不让前端传递,直接在服务端生成:

  • 创建时间戳、操作日志ID等,服务端用new Date()或UUID生成;
  • 用户关联ID,服务端从JWT解析获取,不依赖前端传递。

从根源上消除用户篡改该参数的可能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:52:29