无用户认证时如何保护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,可基于此限制每个用户只能提交/更新自己的分数,避免篡改他人数据:
- 客户端初始化匿名认证:
firebase.auth().signInAnonymously() .then(() => { // 认证成功后进行分数提交 }) .catch((error) => { console.error(error); });
- 配套安全规则:
{ "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
相关产品推荐
相关产品推荐

