安全规则和文档共享应用程序查询

时间:2019-09-18 08:36:02

标签: objective-c firebase firebase-realtime-database firebase-authentication firebase-security

我制作了一个具有协作功能的便笺式应用程序,并希望设置安全的安全规则。 问题是:我的安全规则不适用于我的数据库查询。 当我测试通过身份验证的用户对便笺的访问权限时,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"
    }
  }
}

我希望查询可以使用严格的安全规则(每个用户只能访问其笔记),但是现在它只能使用宽松的安全规则(每个用户都可以访问所有笔记)。

1 个答案:

答案 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。这样的倒排索引还可以使您在扇出(写入)逻辑中实现安全性,而不是在读取操作中实现安全性,从而确保更好的读取可伸缩性。