【问题标题】:Firebase Firestore security rule: Only allow collection group query if filtering by a specific fieldFirebase Firestore 安全规则:如果按特定字段过滤,则仅允许集合组查询
【发布时间】:2023-03-14 23:30:01
【问题描述】:

我想添加一个允许集合组查询的 Firestore 安全规则,但前提是 id 字段上有 where 子句。从本质上讲,我希望用户只有在他/她知道id 的情况下才能检索文档。

换句话说,我愿意这样做:

db.collectionGroup('widgets').where('id', '==', '123').get()

...但不是这个:

db.collectionGroup('widgets').get()

安全规则如下所示:

match /{path=**}/widgets/{widgetId} {
  allow list: if request.query.keys().hasAny(['id']);
}

有没有办法做到这一点?

【问题讨论】:

    标签: firebase google-cloud-firestore firebase-security


    【解决方案1】:

    无法检查查询过滤器的属性。您在查询中可以访问的只是您在documentation for request.query 中看到的内容。根据内容限制对文档的访问的规则始终以将被查询匹配的文档表示。

    您可以将查询限制为一个特定的已知 id:

    allow list: if request.resource.data.id == '123';
    

    或一组 ID,或来自其他来源(例如自定义声明或其他文档)的 ID。

    但是,如果您希望某人仅使用查询中指定的已知“私人”信息获取文档,则该信息必须在文档 ID 本身中,而不是在字段中:

    allow get;  // anyone can get a single document by ID, if they know that ID
    // but do not allow read or list
    

    这可能需要更改您的数据模型,或者可能需要一份由您希望允许的其他 ID 索引的数据副本。

    【讨论】:

    • 看起来不可能做我想做的事。我希望能够访问安全规则中的查询字段,但看起来不可能。我要授予的访问规则是:任何具有已知 id 的人都可以访问该文档。如果文档存储在顶层,那将很容易,因为我只允许 get 请求,但是,文档嵌套在另一个文档的子集合中,并且该路径是未知的,因此集合组查询.看来我需要部署一个云功能才能做到这一点。
    【解决方案2】:

    据我所知,这是不可能的。 request.query 是 3 个属性的映射,即 limitoffsetorderBy ,如 documentation 中所述。话虽如此,request.query.keys() 应该是这样的列表:

    ["limit", "offset", "orderBy"]
    

    这永远不会有一个键 id 并且您的规则将始终返回 false。

    【讨论】:

    • 是的,是的。我在request.query.keys() 上进行了调试输出,结果如下:list_value { values { string_value: "allDescendants" } values { string_value: "ancestor" } values { string_value: "distinct" } values { string_value: "groupBy" } values { string_value: "kind" } values { string_value: "limit" } values { string_value: "offset" } values { string_value: "orderBy" } values { string_value: "selectOnlyKeys" } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2021-09-08
    • 1970-01-01
    • 2019-03-12
    • 2020-09-18
    • 2020-01-28
    • 2020-09-22
    相关资源
    最近更新 更多