使用firestore安全地查询数据--权限被拒绝

问题描述 投票:0回答:1

我在查询firestore的时候,引入了一个规则,却面临着权限拒绝的错误。我把我复杂的规则和过滤器缩小到下面2个例子,其中一个查询成功,一个不成功。我不明白我的失败查询是什么问题。

https:/cloud.google.comfirestoredocssecurityrules-query。 我的理解是,规则不是过滤器。根据这个文件,"如果一个查询有可能返回客户没有权限阅读的文件,那么整个请求就会失败"。"如果一个查询可能会返回客户没有权限阅读的文件,那么整个请求就会失败。"。

考虑到这一点,我对我的规则、过滤器和数据进行了迭代,得出以下结果。

数据:我的 "MyCollection "集合中没有任何数据。事实上,"MyCollection "这个集合从未存在过。

规则:我的失败查询(其中我有 "MyCollection")。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /MyCollection/{id} {
      allow read: if (  
                       (resource.data.readAccess == 0)
                     )

      allow write: if (true)

    }
  }
}

我的失败查询(我的权限被拒绝的错误):

Firestore.instance.collection('MyCollection')
      .where("readAccess", isLessThanOrEqualTo: 0)
      .getDocuments()
      .then((_) => print("Success!"));

当我运行这个查询时,我得到了以下错误信息:

W/Firestore(12491): (21.3.0) [Firestore]: Listen for Query(MyCollection where readAccess <= 0) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

我的成功查询。(这个查询的唯一不同之处是我把 "isLessThan或EqualTo "替换为isEqualTo)

Firestore.instance.collection('MyCollection')
      .where("readAccess", isEqualTo: 0)
      .getDocuments()
      .then((_) => print("Success!"));

评论:当我用数据填充MyCollection时,也有同样的结果。

  • 当我用数据填充MyCollection时,结果也一样。
  • 看起来查询是根据规则进行验证的,而不是像文档中的 "潜在的返回文档 "那样的 https:/cloud.google.comfirestoredocssecurityrules-query。 的状态。如果是这样的话,我想知道如何才能将下面的规则转化为过滤器。

                   (resource.data.readAccess == 0) || 
                   ((request.auth != null) && 
                    (resource.data.readAccess <= get(/databases/$(database)/documents/App/$(resource.data.appId)).data.group[request.auth.uid])
                   )
    
  • 这条规则相当相似,除了它验证文档的readAccess级别 与 "App "文档中该数据的应用的组访问级别,对于登录的用户。如果简单的规则我都不能匹配查询,我无法想象这个复杂的规则需要怎么做。

请赐教。非常感谢。

google-cloud-firestore firebase-security rules
1个回答
2
投票

对于安全规则,查询必须与规则完全匹配。 你所观察到的行为正是我所期望的。

对于这样的规则。

allow read: if resource.data.readAccess == 0;

这意味着查询必须被过滤成这个样子

where("readAccess", isEqualTo: 0)

其他任何东西都不能满足这个规则 这绝对是 要求 在readAccess字段上,查询过滤的值正好是0。 我不清楚为什么你会期待一个不同的结果。

你的查询建议客户端提供它自己对集合的 "访问"。 请注意,这是不安全的。 你不能依靠客户端应用程序在数据库查询中自我报告他们自己的访问级别。 后端的其他东西需要确定应用程序是否被允许进行查询。

通常情况下,Firebase认证用于确定用户是谁,然后根据该用户被允许做什么来允许访问。 你可以将用户的权限存储在另一个文档的某个地方,然后使用该文档的内容来确定他们可以做什么。 或者可能使用自定义的请求。 但是你不能相信用户通过自己的权限。

© www.soinside.com 2019 - 2024. All rights reserved.