firestore中大型群组的安全规则

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

简短版

我正在使用firestore构建一个应用程序,用户可以在其中创建课程,向这些课程添加资源,然后让其他用户注册其课程,从而使他们可以访问其所有资源。我正在努力设置安全规则,以便只有课程组织者或课程成员才能访问资源。我的主要问题是允许用户列出他们已注册的课程中的所有资源,因为列表请求不允许在安全规则中进行查询,因此我需要检查该用户是否是该课程的成员。一种最佳方法是什么使数百(或成千上万)课程成员可以轻松列出所有课程资源,同时确保非会员无法访问它?

[docs的限制部分中特别提到将角色移至大型或复杂组的单独集合中,但是这样做将需要安全规则执行查询以检查访问权限,这对于列表请求是不可能的。] >


完整版本

我正在创建带有客户端直接访问Firestore的Web应用程序原型。消除对后端进行简单数据访问的需求正在刷新,但是我现在真的在努力为我的用例制定正确的数据结构和方法,尤其是围绕实现适当的安全规则。

我已经广泛使用关系数据库,但是对于nosql数据库和firestore来说是相当新的东西,这无济于事。

概念

我的应用程序中的主要集合是用户,课程和资源。用户可以创建可在其中创建学习资源的课程,然后其他用户可以注册这些课程,因此可以访问其中的所有资源。由于仅会邀请一些课程,因此用户无法访问他们不属于的课程资源。

主要要求是:

  • 课程组织者需要对其课程和资源的完全读写访问权限。
  • 课程成员需要对其课程和资源具有完全的阅读权限。
  • 组织者和成员都必须能够轻松列出他们的所有课程,并为每个课程列出他们的所有资源。
  • 组织者和成员应该不能检索有关他们不拥有或不属于的课程或资源的信息。
  • 我的方法

首先,我的方法是大量利用子集合。从组织者的角度来看,用户所学习的课程都具有资源,因此我以这种方式进行了建模。

用户->课程->资源

这里组织者的安全规则也非常简单,因为用户ID是文档路径的一部分,可以使用可用的用户uid轻松检查它(感谢firebase auth)。

match /users/{userId}/courses/{courseId}/resources/{resourceId} {
    allow read, write, update, delete: if (request.auth.uid == userId) 
}

尽管授予成员只读访问权限要困难一些。我需要在某个地方存储该映射。我最终尝试使用用户的子集合来存储它,因此可以通过以下方式查询课程成员资格:/users/{userId}/course_memberships/{courseId}

理论上,我可以编写一个安全规则来授予对课程和资源的读取权限,如下所示:

match /users/{userId}/courses/{courseId}/resources/{resourceId} {
    allow read: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/course_memberships/${courseId})
}

然而,这仅在检索单个文档时有效,列表请求不会评估安全规则中的查询,因此,此设置不允许课程成员查看给定课程中所有资源的列表。

我不知道这里的正确方法是什么,我看到的唯一选择是:

  1. 为每个成员创建一个单独的集合层次结构,其中包含其所有课程和所有资源,包括用于列出其资源的关键信息,并使用云功能对其进行同步。我知道nosql是关于存储非规范化数据的,但是这感觉像是很多额外的数据,尤其是在仅对于安全规则而言是必需的时候。

  2. 将每个成员的uid添加到每个资源上的数组(可以每个数以千计),这也感觉像是很多额外的数据,将这些ID暴露给所有其他似乎错误的成员。

  3. 这里是否有更好的方法,还是Firestore不太适合此类问题?

希望这个问题尚未得到回答,我进行了搜索,但找不到涵盖相同场景的东西。

短版,我正在使用firestore构建一个应用程序,用户可以在其中创建课程,向这些课程添加资源,然后让其他用户注册他们的课程,这将为他们提供...

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

read规则可以分为getlist,后者可以应用于查询。示例:

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