这是我的数据库:
每个密钥都是通过组合用户名创建的。 我想确保只有每条数据中的成员可以访问。
{
"rules": {
"chatroom": {
".write": "auth != null",
"$room_id": {
".read": "$room_id.contains(auth.uid)"
}
}
}
}
由于每个密钥都是通过组合用户名创建的,
我想我可以使用这个
.contains
功能来限制谁可以访问它。
在颤振中,
lastQuery = db.ref('chatroom').orderByChild('date');
data = await lastQuery.limitToLast(10).once();
但是发生了错误:
[firebase_database/permission-denied] 客户端无权访问所需数据。
在所有允许的规则下,此代码可以正常工作。 例如,
{
"rules": {
".read": "true",
".write": "true"
}
}
{
"rules": {
"chatroom": {
".write": "auth != null",
"$room_id": {
".read": "data.child('member').child(auth.uid).val() == true",
}
}
}
}
尝试这个规则,因为成员中的键,值,它是由 UID : Bool 组成的。
这也会导致错误。
我该怎么办?
Firebase 的安全规则不会过滤数据。相反,它们只是确保代码仅尝试读取允许访问的数据。
这就是代码和规则总是齐头并进的原因:代码必须准确请求您希望它能够读取的节点,然后规则必须确保只允许这些请求。
因此,当您在代码中执行此操作时:
lastQuery = db.ref('chatroom').orderByChild('date');
data = await lastQuery.limitToLast(10).once();
规则引擎检查用户是否具有
chatroom
节点的读取权限。由于该节点或其上方没有 .read
子句,因此操作会被拒绝。
虽然您可以在规则中定义查询条件,但这些条件在这里不起作用 - 因为您无法在实际代码中模仿规则中的
contains
操作。
惯用的方法是创建一个“附加”顶级节点,您可以在其中跟踪每个用户有权访问的聊天室 ID。所以类似:
userChatrooms: {
"$uid1": {
"$chatroomId1": true,
"$chatroomId2": true
},
"$uid2": {
"$chatroomId1": true,
"$chatroomId3": true
},
"$uid3" {
"$chatroomId2": true,
"$chatroomId3": true
}
}
首先根据用户的 UID 从
/userChatrooms/$uid
也可以轻松保护此结构。然后从
/chatroom/$chatroomID
chatroom
节点,并且您已经使用当前规则充分保护了对各个房间的访问。另请参阅: