【问题标题】:Firestore Security Rules "exists()” with Query Permissions具有查询权限的 Firestore 安全规则“exists()”
【发布时间】:2019-09-03 23:25:02
【问题描述】:

Firestore 查询似乎不适用于子集合数据结构。

我的数据库结构如下:

users
  userUid
    { userData }
  ...
groups
  groupID
    { groupData }
    members
      member1uid
        { memberData }
      ...
    messages
      message1
        { messageData }
      ...

我的测试用户是否是某个组的成员的规则是这样的:

function isMemberOfGroup(groupId) {
  return exists(/databases/$(database)/documents/groups/$(groupId)/members/$(request.auth.uid))
}

match /groups/{groupId} {
  allow read: if isMemberOfGroup(groupId)
}


问题是我不能使用具有这些规则的查询,因为(我发现)没有办法根据子集合是否包含某个文档进行查询。这意味着我无法列出某个用户所属的所有组。我尝试仅在属于groupData 一部分的地图中列出所有用户,但我无法设置谁可以编辑文档的某些部分的权限,因此这也不起作用。

编辑: 据我了解,查询必须以某种方式匹配规则,否则权限将被拒绝。我将如何创建一个查询来收集某个用户所在的所有组并满足此规则。

【问题讨论】:

  • 我不清楚什么没有按您期望的方式工作。您是否有特定的 sn-p 代码 - 特定用例?此外,很高兴看到一套完整的规则,而不仅仅是一个功能。代码和规则总是相辅相成的。
  • @DougStevenson 我不断收到Missing or insufficient permissions,我什至不知道该尝试什么。
  • 假设安全规则允许所有访问,您会使用什么查询?从你所展示的内容中我不清楚。请记住,您的数据库结构可能不适合您想要使用的查询和规则。
  • 听起来你应该重新表述这个问题,试图获取你想要的数据,而不是安全规则的问题。我建议先解决数据模型和查询,然后再考虑安全规则。
  • 如果成员只能阅读他们所属的组,那么像firebase.firestore().collection('groups').get() 这样的阅读将永远不会起作用。 Firebase 安全规则不会自行过滤数据。相反,它们确定允许哪些读取操作/查询。因此,您将始终必须在查询中复制“仅限成员”逻辑,这只有在有关成员资格的数据在文档本身中时才有可能(因为单个查询/读取只能从单个集合/组中读取)。

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


【解决方案1】:

Firebase 安全规则不会自行过滤数据。相反,它们确定允许哪些读取操作/查询。

因此,如果成员应该只能阅读他们所属的组,那么像 firebase.firestore().collection('groups').get() 这样的阅读将永远不会起作用。

您将始终必须在查询中复制“仅限成员”逻辑。这只有在有关成员资格的数据在文档本身中时才有可能,因为单个查询/读取只能从单个集合/组中读取。由于在您的数据结构中,授权所依赖的数据位于不同的集合中,因此我认为您不能安全地查询它,尽管您可以保护对单个文档的访问。

【讨论】:

  • 谢谢,我明白安全图不过滤数据,我只是想了解如何以符合规则的方式查询数据。我决定改用集合组并按用户 ID 查询 members 集合并获取父文档。
  • 我只是想澄清一下,查询逻辑必须包含文档中的数据,集合规则不可能检查来自用户令牌的自定义声明并且仍然能够查询收藏?
  • 如果您可以将信息放入可以在安全规则内工作的自定义声明中。您可以通过类似 JOIN 的构造查询其他文档(尽管您可以 get() 他们)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 2020-03-22
  • 2018-07-07
  • 2021-03-25
  • 2021-07-17
  • 2018-03-21
  • 2021-02-13
相关资源
最近更新 更多