【问题标题】:Firebase collectionGroup query security rules not workingFirebase collectionGroup 查询安全规则不起作用
【发布时间】:2020-06-16 18:12:13
【问题描述】:

我已经无数次看到这个问题,总是由非常有帮助的@doug-stevenson 回答......但是在仔细阅读这些内容之后,我仍然看不出我做错了什么。

查询(快速): DB.collectionGroup("sessions").whereField("email", arrayContains: "tim@testing.com")

我尝试在这样的规则中硬设置一个值(参见第二条规则):

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /tenants-v1/{tenantId}/{doc=**} {
        allow read: if request.auth != null
                  && get(/databases/$(database)/documents/tenants-v1/$(tenantId)).data.uid == request.auth.uid;
    }

    match /{path=**}/sessions/{session} {
      allow read: if request.auth != null
                     && resource.data.tenantId == 'timsolo';
    }

    match /{document=**} {
      allow read, write: if false;
    }
  }
}

...并确保/tenants-v1/timsolo/galleries/Dzim0sqH9ewwWY7C43oo/sessions/D6Ffo9VYWfcEgXaLVKJb 包含一个字段tenantId,其值为字符串timsolo。

没有按预期工作:查询返回Missing or insufficient permissions.

健全性测试:取出上面第二条规则的最后一行(因此它只允许所有经过身份验证的请求)导致此 collectionGroup 查询按预期工作。

这是怎么回事,为什么我查不到resource.data?

最终的愿望是检查auth.token.tenantIds,一个对令牌的自定义声明,与数据中的值。我更愿意检查resource['__name__'][4],因为这是我真正关心的值,但这也不起作用。无论如何,让我们先开始基本的工作......

【问题讨论】:

  • 您能否分享您的安全规则的完整代码。另外,用于测试规则的确切查询是什么? (我猜不是DB.collectionGroup("sessions").whereField("email", arrayContains: "tim@testing.com"))。
  • @RenaudTarnec 好的,我更新了问题以显示所有规则。不,这确实是用于测试的整个查询...末尾有一个getDocuments 来执行查询,也许您的意思是上面缺少该部分?

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


【解决方案1】:

问题似乎确实来自这部分:

... && get(/databases/$(database)/documents/tenants-v1/$(tenantId)).data.uid == request.auth.uid;

如果您尝试简单地查询/tenants-v1/timsolo/galleries/Dzim0sqH9ewwWY7C43oo/sessions/D6Ffo9VYWfcEgXaLVKJb 文档,则需要在/tenants-v1/timsolo/ 文档中有一个uid 字段,其值对应于经过身份验证的用户的uid。


请注意,您可以使用“Rules Playground”轻松检测到这一点,请参阅doc 了解更多信息。

【讨论】:

  • 嗨 Renaud 感谢您的帮助。我不明白:我认为这 3 条规则中的每一条都有效地 OR'd 在一起,所以任何一个 true 就足够了,而且无论如何只有第二条规则会被使用,因为它是唯一匹配 collectionGroup 查询的规则?
  • ... 碰巧的是,uid 字段确实在 /tenants-v1/timsolo 中,与您指定的 auth.uid 匹配。我认为它不需要用于 collectionGroup 查询,但无论如何它都存在。
  • 我猜overlapping 不适用于这些路径,这些路径不知何故并没有真正重叠(需要更彻底地测试......)。
  • "该 uid 字段确实在 /tenants-v1/timsolo 中,与您指定的 auth.uid 匹配。"这很奇怪,因为根据“规则游乐场”,这个字段应该可以工作。
  • 请注意,我没有使用DB.collectionGroup("sessions").whereField("email", arrayContains: "tim@testing.com") 查询,这显然不适用于这些规则。
猜你喜欢
  • 2021-05-14
  • 2018-01-30
  • 1970-01-01
  • 2018-11-05
  • 2020-08-24
  • 2021-11-03
  • 2021-12-24
  • 2016-06-03
相关资源
最近更新 更多