Firestore 规则多组织多用户访问权限列表数据

Tho*_*søy 6 firebase firebase-security google-cloud-firestore

我正在尝试为我们有以下根集合的新 Firestore 项目设置规则集:

用户

组织

在用户下,我们有 users/userid/ar/organisationid(ar 用于访问权限)

该文件应定义用户对给定组织的访问权限。关键是许多用户可以访问这个 saas 应用程序中的一个或多个组织。

我希望再次检查该组织下的所有文档和所有子集合是否具有此访问权限。

这对于获取和写入非常有效,但数据列表会出现访问错误,我发现限制列表数据的唯一方法是在列出用户 ID 的文档上添加一个数组,并在此客户端进行过滤。这不是一个可在生产中维护的解决方案,因为会有很多包含许多文档的子集合。

有什么建议吗?我可以通过任何其他方式使 Firestore 列表工作吗?有没有更好的方法来构造数据,或者我遗漏了什么?

我能看到的唯一其他方法是使用 firestore 函数来检查列表的服务器端,但是我们在@angular/fire 中丢失了很棒的东西。

过滤客户端的安全性不够好。

谢谢你。

目前的规则:

service cloud.firestore {
  match /databases/{database}/documents {

    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
      match /ar/{organisationDoc} {
        allow read: if request.auth.uid == userId;
        allow write: if false;
      }
    }     

    // read
    match /organisations/{oId} {
      allow get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
      allow list: if request.auth.uid in resource.data.users;

      match /{all=**} {
        allow get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
        allow list: if request.auth.uid in resource.data.users;
      }
    }

    // write
    match /organisations/{oId} {
      allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
      allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
      allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;

      match /{all=**} {
        allow create: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
        allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
        allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;
      }
    }

  }
}
Run Code Online (Sandbox Code Playgroud)

Ren*_*nec 0

您遇到的问题是由“安全规则不是过滤器”这一事实引起的,请参阅此文档

换句话说,您的查询必须过滤用户拥有(读取)访问权限的组织,例如,就像您对“列出文档上的数组usersids”所做的那样。您还可以将组织列表作为用户文档中的数组。

使用云函数“检查服务器端的列表”并(如果我理解正确的话)根据此云函数调用的结果构建查询确实不理想。

但是,您可以使用云函数做的是,当您在 下创建/修改/删除文档时,自动填充/修改列出userids(或)的数组。organizationsorganisationidusers/userid/ar/organisationid


请注意,该文档说:

此行为适用于从集合中检索一个或多个文档的查询,而不适用于单个文档检索

正如您提到的,这就是您的规则适用于该get()方法的原因。