You need to enable JavaScript to run this app. 如何限制用户仅能向Firestore的scores集合提交一次通关用时文档
优惠活动
大模型
产品
解决方案
定价
更多

如何限制用户仅能向Firestore的scores集合提交一次通关用时文档

游戏通关分数Firestore提交的安全落地方案

你当前遇到的问题核心是纯前端直连Firestore的架构下,客户端代码完全可控,仅靠前端逻辑的限制对掌握控制台调试能力的用户完全无效,需要从权限边界、提交校验、服务端兜底三个层面搭建防篡改机制,具体可落地的步骤如下:

一、从规则层堵“无限提交”的口子

这一步不需要额外开发后端,只靠Firestore自身的安全规则就能实现单用户仅可提交一次分数的约束:

  • 先给所有进入游戏的用户绑定稳定的唯一身份,优先用Firebase匿名登录,不需要用户注册就能生成全局唯一的用户uid,避免无身份用户反复刷提交
  • 放弃你当前用随机ID新增文档的写法(也就是add()方法),改成用用户uid作为scores集合的文档ID,从数据结构上保证一个用户只能对应一个分数文档
  • 配置scores集合的写入规则:仅允许已登录用户在对应uid的文档不存在时执行创建操作,一旦文档已存在,后续所有写入请求直接拒绝。这层规则是在Firestore服务端执行的判断,完全不需要信任前端代码,用户就算在前端乱调SDK接口,只要不符合规则就会被直接拦截。

二、从机制上堵“提交任意虚假用时”的漏洞

光限制提交次数还不够,用户依然可以在提交时手动修改time字段,提交远低于真实通关时间的作弊值,这部分可以根据项目规模选择适配的校验方案:

  • 小型项目/个人项目轻量方案:收回前端对scores集合的直接写入权限,仅保留调用云函数的权限。游戏启动时由云函数记录用户的进入时间戳,用户每完成一个关卡节点就上报一次进度,当云函数确认用户完成全部关卡流程、累计时间差符合游戏时长逻辑时,直接由云函数用管理员权限写入对应uid的分数文档。这种模式下前端根本没有直接写scores集合的接口权限,就算用户复制粘贴原来的调用代码,也会因为权限不足写入失败。
  • 更轻量的过渡方案:游戏启动时由Firestore自动下发一个一次性的随机校验凭证,用户通关提交分数时必须携带这个凭证提交,规则层校验凭证有效性、是否被使用过,校验通过后立刻作废凭证,避免用户复用凭证反复提交虚假分数。

注意:不要尝试靠前端控制“提交按钮点击一次后置灰”来防刷,这类逻辑全部运行在用户本地,通过浏览器控制台几行代码就能轻易绕过,所有安全校验逻辑必须放在服务端(Firestore规则/Cloud Functions)执行。

三、你现有代码的最小改造路径

你现在的示例代码db.collection('score').add({ time: 122, });有两个需要优先调整的硬伤:

  • 先把集合名的拼写和你提到的scores对齐(你代码里写的是单数形式的score),避免集合名不统一导致的规则不生效问题
  • 把随机新增的add()改成绑定用户身份的文档写入:db.collection('scores').doc(当前登录用户uid).set({ time: 122, createTime: firebase.firestore.FieldValue.serverTimestamp() })
  • 额外补充字段范围校验:在安全规则里判断提交的time值必须在游戏合理的时长区间内(比如最短通关时间不能低于3秒、最长不能超过游戏设计的总时长),拦截明显不合理的虚假提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 14:24:02