2.3 安全规则心得:默认拒绝、调试与常见误配
安全规则是四大件里最容易被轻视、出事后最致命的一件。这一节讲清楚它的定位、正确的起步姿势,以及那些我见过最多的误配。
规则不是可选项,是真正的防线
先建立一个关键认知:客户端 SDK 是直连数据库的。 你的 App 用户手里拿着的是能直达 Firestore 的连接,中间没有你自己写的服务端把关。服务端项目里,接口层天然是一道闸门;而 Firebase 项目里,唯一站在数据库门前的,就是安全规则。
所以规则不是合规装饰,不是“以后有空再补”的东西。规则没配好,等于把数据库的管理工具连同地址一起发给了用户。正确的心法是四个字:默认拒绝——所有路径默认谁都不许动,然后一条条放开,每放开一条都能说清理由。
// 起步姿势:一切拒绝(示意,以官方文档为准)
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} { allow read, write: if false; }
}
}
规则语言的三块积木
规则表达式主要围绕三个变量展开,理解它们就理解了大半:
| 积木 | 它是什么 | 典型用法 |
|---|---|---|
| auth | 当前登录用户的信息 | 校验请求者 UID 与文档归属字段一致 |
| request | 这次请求本身 | 用 request.resource.data 校验写入数据的类型与范围 |
| resource | 被操作的现有文档 | 比较新旧值,比如价格字段不许客户端改 |
比如“只能改自己的文档”,就是 auth 的用户 ID 等于 resource 里的 owner 字段;“价格字段不许客户端改”,就是比较 request 和 resource 里的价格。数据校验(字段类型、取值范围)也写在这里,规则就是你的数据守门员。
常见误配:三种典型姿势
误配往往不是没配,而是“以为配了”。三种最典型的:
| 常见误配 | 风险 | 正确姿势 |
|---|---|---|
| 把 auth != null 当授权 | 任何注册用户都能读写全库,等于裸奔 | 逐集合限定:进一步校验 UID 与文档归属字段一致 |
| 时间相关校验放客户端 | 客户端时间可随意改,限制形同虚设 | 校验逻辑放到规则里用服务器时间,或交给云函数 |
| 误解规则不递归 | 以为配了上层就覆盖了子路径,下层实际裸露 | 通配符用 recursive 方式显式覆盖全路径,逐层核对 |
第一种最常见。开发图快,写一句“已登录就放行”,项目一路跑到上线。任何能让用户注册的产品,这句规则都约等于不设防。
调试:模拟器是你的好朋友
规则改错了不能拿生产库试。我的工作流是模拟器先行:规则编辑器里的模拟器可以指定操作类型、伪造身份、填入文档数据,跑一遍立刻告诉你允许还是拒绝、卡在哪条规则上。每写完一条新规则,先在模拟器里把“该过的场景”和“不该过的场景”各跑一遍,都符合预期再部署。
模拟器套件(Emulator Suite)更进一步,可以在本地把整个 Firestore 和规则跑起来,配合测试框架做批量断言,团队协作时尤其值得搭一套。规则 Playground 思路也一样:把规则当成有测试用例的代码,而不是配置文件。我的模拟器检查清单:
- 每条新规则先跑“该放行”的场景,确认不误伤;
- 再跑“该拒绝”的场景,确认没有后门;
- 身份分匿名、普通用户、他人三种各过一遍;
- 全部通过才部署,部署记录留档。
一条实用的协作习惯
规则文件跟代码一样进版本管理,每次改动走评审。规则的一行差别就是全库敞开和铁桶的差别,它值得被认真 review。部署节奏上,我习惯规则变更和数据结构变更一起提交,避免出现“字段改了规则没跟上”的真空期。
本节小结
规则是 Firebase 项目唯一的安全防线:默认拒绝起步,用 auth、request、resource 三块积木逐集合放权;别把已登录当已授权,时间校验别信客户端;改动先过模拟器,规则文件进版本管理。做到这几条,绝大多数安全事故与你无缘。
