使用多个级别的get()调用时,Firestore安全规则不起作用

时间:2018-11-04 07:06:12

标签: google-cloud-firestore

为此花了几个小时-非常令人沮丧。

我有一个具有以下数据库的应用程序-comms文档是用户(属于部门的组)要访问的项目,并且仅列出的部门可以访问comms。

/users/user1   { group: /groups/group1 }
/groups/group1 { dept: /depts/dept1 }
/depts/dept1   { }
/comms/comm1   { depts: [/depts/dept1] }

(如果出于某些原因有帮助,也可以发布这些数据库记录的屏幕截图。)

我看到了:

enter image description here

请注意,没有行被突出显示为原因,这使得调试起来很困难,但是从大量的实验/简化示例数据来看,这似乎是由get()间接两个层次触发的:

  • 首先,我们获取用户对象以读取组,
  • 然后通过get()用户组读取部门。

如果我通过按组而不是按部门划分comm ACL来简化数据库,使其仅需要一层间接访问,则规则起作用。

/comms/comm1 { groups: [/groups/group1] }

即使我可以摆脱部门的困扰,我仍然可以轻松应对各种级别的间接访问-我只需要检查组对象中的字段,例如:

allow write: if get(user().data.group).data.isActive;

这是完整的规则代码:

service cloud.firestore {
  match /databases/{database}/documents {
    function userPath() {
      return /databases/$(database)/documents/users/$(request.auth.uid);
    }
    function user() {
      return get(userPath());
    }
    match /users/{userId} {
      allow read: if true;
      allow write: if userId == request.auth.uid;
    }
    match /comms/{commId} {
      allow read, write: if get(user().data.group).data.dept in resource.data.depts;
    }
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

1 个答案:

答案 0 :(得分:0)

在示例数据中,您将用户组指定为

/users/user1   { group: /groups/group1 }

在获取中,您将尝试访问/ groups / group1,这里缺少的是/ databases / $(database)/ documents路径,这很可能就是您的get不返回任何内容的原因。