想象一下,我们有聊天应用程序,并且在此应用程序中,我们有很多房间,有些房间是私人的,有些则适合所有人。每个房间都有一个可以管理用户(可以邀请和删除)的管理员。只有会议室成员可以读取和写入消息。管理员是在这种情况下创建房间的人。
我想在创建房间时创建安全规则,并在membersChange上对其进行更新,以便只有成员才能读写留言板的内容。
在这种情况下,它就是这样:
databse/rooms/
private1
admin: memberX
members: member1, member2
//only admin can write into members fields
messages
message1...
message2...
message3...
//only members can write and read messages
private2
admin: memberXY
members: member1, member4
//only admin can write into members fields
messages
message1...
message2...
message3...
//only members can write and read messages
是否可以通过云功能创建和更新安全规则,而不是在Firebase控制台中手动更新安全规则?还是有任何方法可以自动执行此过程?
我注意到我可以deploy security rules using CLI。这里的程序应该是什么?我什么时候叫它?如何从数据库中获取成员?
编辑: 对于任何需要更多信息的人,请查看How to Build a Secure App in Firebase
答案 0 :(得分:2)
我会重新考虑这个模型。我看到了几种可行的方法,而不是一直更新安全规则:
选项1
您可以保存哪些用户可以访问Firestore上的特定房间,然后根据安全规则访问该房间的文档,并查看授权用户列表中是否有经过身份验证的用户。这样做的问题是成本,因为这将触发每个操作额外的数据库读取,这可能会变得昂贵。
选项2
您可以使用云功能为用户创建自定义声明,如下所示:
admin.auth().setCustomUserClaims(uid, {"rooms": "room1,room2"})
然后根据安全规则,您可以检查用户是否对特定房间拥有所有权:
match /rooms/{roomId} {
allow read: if roomId in request.auth.token.rooms.split(',');
}
我相信您也可以将声明直接保存为数组,但我尚未对其进行测试。
对于此选项,您需要考虑令牌的大小,令牌的大小是有限制的,如果令牌太大,则会导致性能问题。根据您的方案,您可以创建较小的权限集,然后将其设置为房间和用户。
选项3
您可以保存可以访问每个文档的用户的uid,然后检查该文档上是否存在经过身份验证的用户的uid。但是,如果您有太多的用户,这可能会失控。
如果您的情况有意义,我会选择选项2。或者,您可以结合使用其中一种以上的技术。我的想法是展示一些可能性,以便您可以选择最适合自己的方式。
答案 1 :(得分:2)
为每个房间设置不同的规则并动态更新规则是一个坏主意。以下是此解决方案引起的几个问题:
相反,您首先可以将数据结构分为公共房间和私人房间:database/rooms/public/...
和database/rooms/private/...
。
要保护您的私人房间,您可以看一下rules conditions并执行类似的操作:member can read/write IF his UID is in /members
(伪代码,将无法正常工作)。
您可以查看this question作为示例。