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

基于Fat Free Framework,如何防止高分提交POST请求被篡改?

高分提交防篡改的优化方案

针对你用Fat Free Framework开发小游戏合集时遇到的参数篡改问题,给你几个比全量改写session逻辑更高效的方案:

1. HMAC请求签名(最推荐)

这个方案不用大改现有提交逻辑,核心是给参数加个“防伪标签”,后端通过验证标签合法性判断参数是否被篡改:

实现步骤:

  • 游戏初始化阶段:后端生成随机签名密钥,存入用户session并返回给前端
    // Fat Free框架内的代码示例
    $signingKey = bin2hex(random_bytes(16)); // 生成16字节随机密钥转十六进制
    $f3->set('SESSION.signing_key', $signingKey);
    // 将密钥通过游戏初始化接口响应返回给前端
    echo json_encode(['signing_key' => $signingKey]);
    
  • 前端提交高分时:用HMAC算法(如SHA256)将game、score与签名密钥拼接生成签名,随参数一起提交
    // 假设已获取后端返回的signingKey
    const game = "Tetris";
    const score = player.score;
    // 用CryptoJS生成签名,注意拼接规则前后端必须完全一致
    const signature = CryptoJS.HmacSHA256(`${game}:${score}`, signingKey).toString();
    
    $.ajax({
      "url": "/submitHighscore",
      "type": "post",
      "data": {
        "game": game,
        "score": score,
        "signature": signature
      }
    });
    
  • 后端验证逻辑:从session取出密钥,用相同规则计算签名并与前端传入的对比,一致则执行入库
    // 在/submitHighscore路由中
    $game = $f3->get('POST.game');
    $score = $f3->get('POST.score');
    $receivedSignature = $f3->get('POST.signature');
    $signingKey = $f3->get('SESSION.signing_key');
    
    // 计算预期签名
    $expectedSignature = hash_hmac('sha256', "$game:$score", $signingKey);
    
    if ($expectedSignature === $receivedSignature) {
        // 签名合法,执行高分入库逻辑
    } else {
        // 签名不匹配,拒绝请求
        $f3->error(403, 'Invalid request');
    }
    

优点:参数被篡改后签名必然失效,还可结合一次性随机数(Nonce)防重放攻击,代码改动量极小。

2. 后端分数合理性校验(兜底必备)

不管用什么前端防篡改方案,后端都应该加一层基于游戏规则的分数校验,从逻辑层面过滤异常分数:

  • 示例代码(根据不同游戏规则调整):
    function isScoreValid($game, $score) {
        switch($game) {
            case 'Tetris':
                // 假设单局最高分不超过10000,且分数为100的倍数(按实际规则调整)
                return $score > 0 && $score <= 10000 && $score % 100 === 0;
            case 'Snake':
                // 蛇形游戏的分数规则校验
                return $score > 0 && $score <= 5000;
            default:
                return false;
        }
    }
    
    // 在提交逻辑中调用校验
    if (isScoreValid($game, $score)) {
        // 分数合法,继续执行
    } else {
        $f3->error(400, 'Invalid score');
    }
    

优点:完全不需要改动前端代码,纯后端逻辑就能过滤大部分离谱的篡改分数。

3. 轻量化Session方案(折中选择)

如果不想加签名逻辑,可以只在session中存储用户当前正在玩的游戏,前端提交时只传score,后端对比session中的游戏与前端传入的game是否一致,再结合分数校验:

  • 游戏开始时:
    $f3->set('SESSION.current_game', 'Tetris');
    
  • 后端验证:
    $submittedGame = $f3->get('POST.game');
    $currentGame = $f3->get('SESSION.current_game');
    
    if ($submittedGame !== $currentGame) {
        $f3->error(403, 'Invalid game');
    }
    // 再执行分数合理性校验
    

优点:改动量远小于全量存储分数的session方案,能有效防止篡改game参数,配合分数校验可覆盖大部分篡改场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:35:29