Firestore中大型团体的安全规则

时间:2019-12-30 11:16:40

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

短版

我正在使用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})
}

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

我无法确定这里的正确方法是什么,我看到的唯一选择是:

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

  

允许列表:如果[condition];

More information can be found here