Firestore Javascript查询与此安全规则结构匹配的内容

Geo*_*rey 5 javascript google-cloud-firestore firebase-security-rules

我在Firebase控制台中为Firestore测试了这个安全规则结构,我认为它符合我的要求,即在组织级别为用户保留角色映射,并通过始终使用该方法引用父组织来强制执行组织子集合的权限get().

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

    // ORGANIZATIONS collection
    match /organizations/{organization} {

      function isSignedIn() {
        return request.auth != null;
      }
      function getRole(rsc) {
        // Read from the 'roles' map in the resource (rsc)
        return rsc.data.roles[request.auth.uid];
      }
      function isOneOfRoles(rsc, array) {
        // Determine if the user is one of an array of roles
        return isSignedIn() && (getRole(rsc) in array);
      }

      allow write: if isSignedIn();
      allow read: if isSignedIn() && isOneOfRoles(resource, ['owner']);

      // PROJECTS subcollection
      match /projects/{project} {

        allow write: if isSignedIn() && isOneOfRoles( get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
        allow read: if isSignedIn() && isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,因为查询必须符合安全规则,我试图了解如何使用符合上述安全规则的Javascript客户端进行查询.

我有一个工作查询,以使组织看起来像这样:

db.collection('organizations').where(`roles.${currentUser.uuid}`, '==', 'owner').get()
Run Code Online (Sandbox Code Playgroud)

它基于如下文档结构:

organizations (collection)
  {organization} (document)
    name: string,
    roles: { 
      <user_id_1>: "owner",
      <user_id_2>: "member"
    },
    projects (subcollection)
Run Code Online (Sandbox Code Playgroud)

是否可以在Javascript客户端中进行查询(甚至多个查询),检查该用户是否是该organization级别的特定角色并检查projects子集合中的文档属性,类似于安全规则的作用?

编辑:最后,我认为这是一个问题,authorization以及Firestore是否支持我的方法.在这一点上,我最好的选择是递归通配符语法 - match /organization/{document=**}但由于匹配任何条件都允许访问所有嵌套文档,因此这种方法似乎不太安全.

理想情况下,我可以organizations/{organization}/projects在我的客户端查询中指定一个集合路径 - 例如,- 并指定{organization}在授予对projects子集合的访问权限之前必须检查角色.

可能的解决方案:以下安全规则结构有很多不足之处,但似乎是一种改进.我只是使用递归通配符语法而不是匹配特定子集的路径.有谁知道更好的解决方案?

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

    function isSignedIn() {
      return request.auth != null;
    }
    function getRole(rsc) {
      // Read from the 'roles' map in the resource (rsc)
      return rsc.data.roles[request.auth.uid];
    }
    function isOneOfRoles(rsc, array) {
      // Determine if the user is one of an array of roles
      return isSignedIn() && (getRole(rsc) in array);
    }

    // ORGANIZATIONS
    match /organizations/{organization} {

      allow write: if isOneOfRoles(resource, ['owner']);
      allow read: if isOneOfRoles(resource, ['owner', 'member']);

    }

    // Any subcollections under ORGANIZATION
    match /organizations/{organization}/{sub=**} {

      allow write: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
      allow read: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);

    }
  }
}
Run Code Online (Sandbox Code Playgroud)