Firestore安全规则 - {wildcard}在获取集合时既不为null也不为null

问题描述 投票:-1回答:2

我已经在我的firestore上设置了一个读取规则,并且在按ID获取单个文档时它工作正常,但在获取集合时失败并出现FirebaseError: Missing or insufficient permissions.错误。

在查询集合时,似乎路径中的通配符无法正确绑定。我已经归结为一个最小的例子,我从逻辑上认为不应该失败许可,但确实如此。它如下:

数据(格式化,但当然在收集/文档中组织):

"items": {                   // collection "items"
   "item1" : {               // document "item1"
      "name": "first item"   // just dome dummy data
   }
}

规则:

service cloud.firestore {
    match /databases/{database}/documents {
        match /items/{itemId} {
            allow read: if itemId != null;
        }
    }
}

我用来访问数据库的代码(typescript)

// This line works fine, returns the document
firebase.firestore().collection("/items").doc("item1").get()

// This line gets a "FirebaseError: Missing or insufficient permissions." error
firebase.firestore().collection("/items").get()

我试过将规则改为

allow read: if itemId != null || itemId == null;

从逻辑上讲,这应该始终如一。但是,结果仍然相同,这让我相信绑定到itemId通配符存在一些问题。

正如理智检查一样,我也将规则改为

allow read: if true;

现在,集合上的get()和文档都可以正常工作(如预期的那样),没有任何权限错误。

所以我在这里遗漏了什么,或者这是firestore中的一个bug?

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

您提议的规则不起作用,因为(因为它是当前实现的),通配符变量具有列表(查询)类型请求的未定义值(但不是get类型请求,因为文档ID当然是直接来的来自客户)。查询可能与多个文档匹配,并且您的查询未指定文档ID,因此无法在规则中使用。

如果您希望规则在每个文档的基础上决定它是否属于查询结果,那么它也永远不会起作用。这是因为规则不是过滤器。所有过滤器都必须来自客户端。如果规则拒绝给定过滤器可能存在的任何文档,则拒绝整个请求。 (在请求时实际检查所有文档是不可扩展的 - 这可能非常慢)。

换句话说,如果要影响查询,请不要使用通配符变量。仅使用可匹配的文档的属性,并确保客户端指定所有相关的过滤器。


1
投票

首先,你的规则对我没有意义。检查文档ID是不是null的目的是什么?有效文档无法拥有null文档ID。


来自Queries and security rules

在编写查询以检索文档时,请记住安全规则不是过滤器 - 查询是全部或全部。为了节省您的时间和资源,Cloud Firestore会针对其潜在结果集评估查询,而不是针对所有文档的实际字段值。如果查询可能返回客户端无权读取的文档,则整个请求将失败。

在您的情况下,firestore可能认为您的查询可能会返回您可能无权阅读的文档。它以某种方式认为某些文档可能具有null文档ID,从而拒绝整个请求。

当您将规则更改为allow read: if true;时,它可以正常运行,因为Firestore会对其进行评估,并且知道该规则肯定会为每个文档传递,因此授予您读取权限。

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