【问题标题】:Firestore security rule works for delete and update but not for read?Firestore 安全规则适用于删除和更新,但不适用于读取?
【发布时间】:2021-09-10 21:54:45
【问题描述】:

我的安全规则中有以下功能

function isSignedIn() {
    return request.auth != null;
}

function getRole(workspaceId) {
    return get(/databases/$(database)/documents/roles/$(workspaceId)/members/$(request.auth.uid)).data.role
}

     
function isOneOfRolesOtherResource(rsc, array) {
  return isSignedIn() && (getRole(rsc.data.workspace_id) in array);
}

以及我的任务集合的以下规则。

match /tasks/{document=**} {
      allow create: if isOneOfRolesOtherResource(request.resource, ['ADMIN', 'MANAGER', 'MEMBER', 'GUEST']);
      allow read: if isOneOfRolesOtherResource(resource, ['ADMIN', 'MANAGER', 'MEMBER', 'GUEST']);
      allow update, delete: if isOneOfRolesOtherResource(resource, ['ADMIN', 'MANAGER', 'MEMBER', 'GUEST']);
}

我的读取、更新和删除规则完全相同,但由于某种原因,我的读取规则权限不足,而更新和删除工作正常。如果我将读取规则更改为已登录,我也没有问题。在 firestore 操场上,读取规则通过。我似乎无法弄清楚发生了什么。

这是我在我的应用程序中的查询,再次使用登录验证时,这个观察者工作正常。

const query = db
.collection(TASKS_STORENAME)
.where('project_id', '==', activeProject.value.id);



projectTasksObserver = query.onSnapshot(
    (querySnapshot) => {
      querySnapshot.docChanges().forEach((change) => {
        const taskData = change.doc.data() as TaskData;
        const task = Task.deserialize(taskData);
        console.log('task change type:', change.type);
        if (change.type === 'added') {
          addProjectTask(task);
        }
        if (change.type === 'modified') {
          updateProjectTask(task);
        }
        if (change.type === 'removed') {
          removeProjectTask(task);
        }
      });
    }

有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    想通了。问题是我的查询不够具体,所以谷歌认为我的权限不足。

    添加工作区过滤器有效。

    const query = db
    .collection(TASKS_STORENAME)
    .where('workspace_id', '==', activeProject.value.workspace_id)
    .where('project_id', '==', activeProject.value.id);
    

    【讨论】:

      【解决方案2】:

      问题出在规则的范围内。您的 createupdatedelete 规则始终针对单个文档,然后规则引擎可以检查其目标资源是否包含必要的值。

      您的read 规则涵盖get(读取单个文档)和list(查询/读取多个文档),在后一种情况下,Firestore 必须检查每个当前和未来的文档,这将是禁止的为了表现。文档在rules are not filters 下对此进行了介绍。

      规则本身不是过滤器,但它们只是强制您不要尝试读取未经授权的数据。解决方案是(正如我看到您自己也想通了),在您的查询中包含您的规则强制执行的相同条件。

      【讨论】:

        猜你喜欢
        • 2021-03-30
        • 2019-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-05
        • 2018-04-02
        • 1970-01-01
        • 2021-05-14
        相关资源
        最近更新 更多