我制作了一个具有协作功能的便笺式应用程序,并希望设置安全的安全规则。 问题是:我的安全规则不适用于我的数据库查询。 当我测试通过身份验证的用户对便笺的访问权限时,Firebase安全规则模拟器会显示正确的结果。 但是在应用程序中,我收到消息“ / notes失败的监听器:Permission_denied”。
我在这里找到了一些很好的安全规则示例 Firebase: Security rules for a collaborative app 和这里 https://gist.github.com/katowulf/4741111 但是这些与我没有什么不同。 我怀疑问题可能出在查询中或缺少索引规则(“ .indexOn”)。
我的查询是:
- (void)setupQuery {
NSString *email = [FirebaseAuthorization shared].currentUserEmail;
self.reference = [[[FIRDatabase database] reference] child:@"notes"];
NSString *query = [NSString stringWithFormat:@"document/users/%@", email.MD5String];
self.query = [[self.reference queryOrderedByChild:query] queryEqualToValue:@(YES)];
}
我的安全规则是:
{
"rules": {
"notes" : {
"$note_id" : {
".read": "data.child('document/users/'+root.child('users/'+auth.uid+'/email_md5').val()).val() === true",
".write": "(data.child('document/users/'+root.child('users/'+auth.uid+'/email_md5').val()).val() === true) || (root.child('users/'+auth.uid+'/email').val() === root.child('users/'+newData.child('document/author').val()+'/email').val())",
".indexOn": "document/users"
}
},
"users" : {
"$user_id" : {
".read": "auth.uid === $user_id",
".write": " ( auth.uid == newData.val() ) || ( auth.uid == $user_id )"
}
}
}
}
我的数据库结构是:
{
"notes" : {
"NOTE_ID_1" : {
"document" : {
"author" : "user_id_1",
"users" : {
"email_1_md5@email-com" : true,
"email_2_md5@email-com" : true
}
}
}
"NOTE_ID_2" : {
"document" : {
"author" : "user_id_2",
"users" : {
"email_3_md5@email-com" : true,
"email_4_md5@email-com" : true,
}
}
}
}
"users" : {
"iser_id_1" : {
"email" : "email_1@email.com",
"email_md5" : "email_2_md5@email-com"
}
}
}
我希望查询可以使用严格的安全规则(每个用户只能访问其笔记),但是现在它只能使用宽松的安全规则(每个用户都可以访问所有笔记)。
答案 0 :(得分:1)
Firebase安全规则不会代表您过滤数据。他们只是强制要求所有数据访问均已获得授权。
这是您查询的代码
self.reference = [[[FIRDatabase database] reference] child:@"notes"];
NSString *query = [NSString stringWithFormat:@"document/users/%@", email.MD5String];
self.query = [[self.reference queryOrderedByChild:query] queryEqualToValue:@(YES)];
要运行此代码,用户必须在notes
处具有某种形式的读取权限。由于没有人对该节点具有读取权限,因此规则引擎会拒绝读取。
在文档中以及其他许多rules are not filters中,这被称为questions about the topic。
请注意,您现在可以使用安全规则通过query-based rules允许对某些查询进行读取。使用此功能时,您可以在代码中构建相关查询,然后使用安全规则仅允许使用该特定查询访问数据。
在您的情况下,这将是.read
上的/notes
规则,它与您要建立的查询相匹配。对于您的用例,应该是这样的
{
"rules": {
"notes" : {
".read": "
query.orderByChild == 'document/users/'+auth.uid &&
query.equalTo == true
"
}
}
}
但是请注意,我不确定此条件是否确实符合您的查询。
即使这样做,缺少索引也会使安全点变得毫无意义(因为如果没有索引,则所有筛选都在客户端上进行)。有关更多信息,请在这里查看我的答案:Firebase query if child of child contains a value。这样的倒排索引还可以使您在扇出(写入)逻辑中实现安全性,而不是在读取操作中实现安全性,从而确保更好的读取可伸缩性。