Firestore安全规则get函数调用规范及越权读取问题排查
Firestore安全规则问题分析与修复
核心问题
最外层规则完全开放权限:
你的规则最外层写了match /{document=**} { allow read, write: if true; },这个通配符会匹配所有Firestore文档路径,直接允许所有读写操作,导致后续所有子规则的权限限制完全失效——不管子规则怎么写,最外层的允许规则已经优先生效了。路径匹配语法错误:
你用match /{users}/{eID}这种写法时,{users}是一个路径占位符,不是匹配名为users的集合,正确写法应该是match /users/{eID}(直接写集合名,不用大括号包裹)。同理后续的match/{userA}/{eID}、match/{exclusiveA}/{preferredCurrency}都是错误的路径匹配方式,无法定位到你实际的集合。规则层级逻辑混乱:
子规则的嵌套层级不符合你的Firestore实际结构,导致权限条件无法作用到目标集合exclusiveA上。
修复后的规则示例
假设你的Firestore结构是:users/{用户ID}/exclusiveA/{文档ID},且用户文档(users/{用户ID})包含currency字段,exclusiveA下的文档包含preferredCurrency字段,修复后的规则如下:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 默认拒绝所有操作,仅开放需要的路径权限 match /{document=**} { allow read, write: if false; } // 匹配users集合下的用户文档 match /users/{userId} { // 允许用户读写自己的文档 allow read, write: if request.auth != null && request.auth.uid == userId; // 匹配用户文档下的exclusiveA子集合 match /exclusiveA/{docId} { allow read: if request.auth != null // 验证用户未绑定信用卡(根据原规则逻辑) && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.creditCard == 'false' // 匹配用户currency与文档的preferredCurrency && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.currency == resource.data.preferredCurrency; } } } }
关键优化说明
- 默认拒绝所有权限:先通过最外层规则拒绝所有操作,再针对需要开放的路径单独配置权限,这是Firestore规则的最佳实践,避免因宽泛规则导致权限泄露。
- 优化get函数调用:可以将用户文档的查询结果缓存,避免重复调用
get提升性能:allow read: if request.auth != null { let userDoc = get(/databases/$(database)/documents/users/$(request.auth.uid)).data; return userDoc.creditCard == 'false' && userDoc.currency == resource.data.preferredCurrency; } - 集合查询适配:如果你的代码是对
exclusiveA进行集合查询(而非单文档get),上述规则已支持自动过滤不符合条件的文档——resource.data代表查询结果中的每个文档数据,Firestore会自动拦截不满足条件的内容。
验证步骤
- 使用Firebase控制台的规则模拟器,分别测试符合条件和不符合条件的读取请求,确认权限是否生效。
- 在代码中测试读取操作,检查是否只能获取到
preferredCurrency与用户currency匹配的文档。
内容的提问来源于stack exchange,提问作者mathems32
相关产品推荐
相关产品推荐

