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

无用户认证时如何保护Firebase实时数据库配置并防恶意刷分?

解决方案建议

关于Firebase配置信息的安全性

Firebase Web端的配置信息(包括API密钥、Database URL等)本身就是设计成可公开的,即使编译后被获取,只要安全规则配置得当,攻击者无法通过这些信息滥用你的数据库。所以不用过度纠结.env文件编译后暴露的问题,核心安全防线是Firebase安全规则。

必须重视当前规则的风险

你当前的完全开放规则(.read和.write都设为true)极度危险,任何人都可以读写、篡改甚至删除你的排行榜数据,恶意刷分只是其中一种风险,必须立即修改。

无用户认证场景下的安全规则方案

以下是几种适合无认证(或匿名认证)场景的规则配置思路,可组合使用:

1. 限制写入内容的合法性

强制验证提交的分数格式、范围,防止恶意提交无效或夸张的数据:

{
  "rules": {
    "leaderboard": {
      // 允许所有人读取排行榜
      ".read": true,
      // 写入时验证:分数是正数且不超过合理上限(比如10000),同时包含必要字段
      ".write": "newData.hasChildren(['username', 'score', 'timestamp']) && 
                 newData.child('score').isNumber() && 
                 newData.child('score').val() > 0 && 
                 newData.child('score').val() <= 10000 && 
                 newData.child('timestamp').val() <= now"
    }
  }
}

2. 限制请求来源(辅助防护)

通过验证请求的referer头,仅允许你的游戏域名发起请求(注意:referer可被伪造,仅作为辅助手段):

{
  "rules": {
    "leaderboard": {
      ".read": true,
      ".write": "request.headers.referer matches /^https://your-game-domain\\.com/ && 
                 // 加上内容验证规则
                 newData.hasChildren(['username', 'score', 'timestamp']) && 
                 newData.child('score').isNumber() && 
                 newData.child('score').val() > 0 && 
                 newData.child('score').val() <= 10000"
    }
  }
}

替换your-game-domain.com为你的实际游戏域名。

3. 限制提交频率

防止同一客户端短时间内批量刷分,可通过now和上次写入时间判断:

{
  "rules": {
    "leaderboard": {
      "$entryId": {
        ".read": true,
        ".write": "// 内容验证
                   newData.hasChildren(['username', 'score', 'timestamp']) && 
                   newData.child('score').isNumber() && 
                   newData.child('score').val() > 0 && 
                   newData.child('score').val() <= 10000 &&
                   // 限制1小时内只能更新一次
                   (data.exists() ? now - data.child('timestamp').val() > 3600000 : true)"
      }
    }
  }
}

4. 采用匿名认证(推荐)

无需用户手动登录,Firebase自动为每个访客分配匿名ID,可基于此限制每个用户只能提交/更新自己的分数,避免篡改他人数据:

  1. 客户端初始化匿名认证:
firebase.auth().signInAnonymously()
  .then(() => {
    // 认证成功后进行分数提交
  })
  .catch((error) => {
    console.error(error);
  });
  1. 配套安全规则:
{
  "rules": {
    // 存储每个匿名用户的分数
    "userScores": {
      "$uid": {
        // 仅允许当前匿名用户写入自己的节点
        ".write": "auth != null && auth.uid === $uid",
        ".read": false,
        // 验证分数合法性
        ".validate": "newData.hasChildren(['username', 'score']) && 
                      newData.child('score').isNumber() && 
                      newData.child('score').val() > 0 && 
                      newData.child('score').val() <= 10000"
      }
    },
    // 排行榜数据通过云函数从userScores同步,仅允许读取
    "leaderboard": {
      ".read": true,
      ".write": false
    }
  }
}

这种方式可以进一步隔离写入权限,结合云函数同步排行榜还能避免客户端直接修改排行榜数据,安全性更高。

额外建议

  • 若游戏逻辑允许,可在云函数中加入更复杂的验证(比如校验分数生成的合理性),彻底防止客户端作弊。
  • 定期测试安全规则,使用Firebase控制台的“规则模拟器”验证读写权限是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:33:14