问题:
对于以下不同的顶级消防仓库集合,如何限制访问除一条路径外的所有路径?
我们正在Firestore中构建一个数据架构,以支持多所学校教师的聊天应用程序。
顶级消防仓库系列包括:
/siteAdminUsers
/schools
/schools/{schoolId}/teachers
/schools/{schoolId}/chats
下面是我们现在正在尝试的安全规则设置-我们检查的地方:
- 有效的用户身份验证
- userClaim变量
request.auth.token.chatFlatList
中存在预期值
但是,/messages
的读取侦听器被阻止。
错误消息:
FirebaseError:[代码=权限被拒绝]:缺少或权限不足
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
详细信息
我们对所有数据的读/写都使用云功能,所以在几乎所有情况下,我们都可以阻止所有客户端访问。
一个例外是聊天讨论,我们需要在移动客户端中设置一个快照侦听器,以了解何时有新消息。
子集合注释:
在学校,有针对学校工作人员(教师、行政人员等(的讨论会
/schools/{schoolId}/chats/{discussionId}
其中每个讨论文档包含:
- 参与者教师id列表
- 实际消息的子集合,其中每个文档都是单独发布的消息:
/schools/{schoolId}/chats/{discussionId}/messages
云功能的用户声明代码
通过查看云功能日志,我们已经验证了userClaim是否已被设置。
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
更新#1
尝试了以下变体,其中规则跳过/省略对userClaim和auth.token.的检查
然而,仍然存在相同的权限错误。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
我认为这里的问题是您正在编写一个名为messages的集合规则。
所有匹配语句都应该指向文档,而不是集合。https://firebase.google.com/docs/firestore/security/rules-structure
您应该尝试在消息路径后添加/{document=**},类似于:
match /schools/{schoolId}/chats/{discussionId}/messages/{document=**} {
allow write: if false;
allow read: if request.auth != null;
}
如果我想读写所有集合,而不是一个名为"backStage";;
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{collection}/{document} {
allow read: if true
allow write: if (collection != "backStage");
}
}
}
这里有一个解决方案(似乎正在运行(,它包括检查子字符串的chatFlatList
用户声明变量(来自原始问题(:
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token.chatFlatList.matches(discussionId);
}
这要归功于:
基于自定义参数的Firebase存储规则
- 这里的帖子显示没有任何
$
表示法来访问路径变量。我记得在安全规则示例代码示例中看到过这一点-也许它特定于数据库层
- 这里的帖子显示没有任何
https://firebase.google.com/docs/reference/security/storage/#string
https://regex-golang.appspot.com/assets/html/index.html
- 在这里尝试一些示例输入,以了解如何创建正则表达式