能否叠加Firestore安全规则省略OR运算符配置管理员权限
Firestore全局管理员安全规则写法说明
你这种全局配置管理员权限、省略各规则内|| isAdmin()判断的写法技术上完全生效,只要做好风险管控就属于很实用的实践,不是反模式。
核心判定逻辑
Firestore安全规则的放行规则很明确:
一个请求只要命中任意一条匹配路径的
allow规则、且对应条件返回true,就会直接放行,不存在“优先级高的具体规则覆盖宽泛全局规则”的逻辑,也没有原生的deny拒绝机制。
你写的全局通配匹配match /{document=**}会覆盖数据库下所有路径的文档,管理员发起请求时这个块的isAdmin()条件直接返回true,自然会获得全库读写权限,完全不需要在每个单独集合的规则里重复加管理员判断。
这种写法的好处
- 少写很多重复代码:不用给每个集合的读、写规则都冗余追加
|| isAdmin(),后续新增集合规则时也不会漏加管理员权限 - 维护更方便:如果之后要调整管理员的判定逻辑,只需要改
isAdmin()函数本身就行,不用挨个集合翻规则修改
必须注意的风险
这种写法的影响范围是整个数据库,用的时候一定要把以下管控做到位,不然很容易出严重的安全事故:
- 首先必须锁死管理员字段的修改权限:你现在的
isAdmin()逻辑是读userProfiles集合下对应用户的admin字段,必须给userProfiles配极严格的写规则,绝对不能让普通用户能改自己或者别人文档里的admin字段,不然普通用户随便把自己字段改成true就能拿全库权限,风险极大。 - 改全局规则的时候要慎之又慎:全局match块的任何改动都会影响所有集合,别随便在全局块里加宽松的放行条件,改完一定要用规则模拟器把常见场景都测一遍。
- 这种写法没法单独给某个集合收回管理员权限:因为只要有一条allow匹配就放行,如果你之后有个集合存特别敏感的内容、连管理员都不让直接访问,这种全局写法实现不了,遇到这种场景就得删掉全局管理员规则,回到每个集合单独写判断的模式。
顺手提个你现有规则的bug
你现在写的isOwnDocument()函数有问题:读请求里根本不存在request.resource对象(这个对象只有写请求里才有,代表要写入的新内容),读的时候调用这个函数会直接报错,把请求拒掉。
要判断访问的是不是用户自己的文档,最稳妥的写法是直接拿路径里的变量,比如:
match /userSettings/{userId} { allow read, write: if request.auth.uid == userId; }
不用绕弯子封装函数取资源id,还能避免读写场景对象不一样导致的报错。
内容的提问来源于stack exchange,提问作者lurning too koad
相关产品推荐
相关产品推荐

