如何制定Firebase规则,允许身份验证用户阅读所有文档,但仅创建自己的用户文档而不赋予管理员权限?

时间:2019-08-17 16:00:41

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

我正在努力解决Firebase安全规则,我可以使其一部分正常工作,但是当我尝试将它们全部连接在一起时,我遇到了问题。
我想让我的规则执行以下操作:

  1. 如果已验证,则允许阅读所有文档

  2. 仅通过在文档/databases/$(database)/documents/users/$(request.auth.uid)上进行身份验证,才可以创建或更新用户文档,但不将admin添加到角色数组 !(getAfter(/ databases / $(database)/ documents / users / $(request.auth.uid))。data.roles中的“ admin”)

  3. 仅允许getRole(“ admin”)== true来创建,编辑或删除任何用户文档和任何其他文档

function getRole(role) {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
  }

这是我所拥有的,不包括能够创建自己的用户帐户的用户。它只允许管理员写任何文档。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
  function getRole(role) {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
  }
    match /{document=**} {
      allow read: if true;
      allow write: if getRole('admin') == true;
    }
  }
}

这是我尝试添加的内容,以允许用户创建其用户文档。它似乎并没有遵循下一条规则,它尝试在match /{document=**}路径中使用getRole并发现用户不是管理员,因此失败。我尝试重新排序/ users /路径,然后通过该路径,然后执行相同的操作,并再次在/{document=**}路径中的getRole上失败。我还尝试指定文档名称而不是使用通配符,这似乎不允许任何获取或写入。你能指出我正确的方向吗?

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
  function getRole(role) {
    return exists(/databases/$(database)/documents/users/$(request.auth.uid)) && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
  }
    match /{document=**} {
      allow read: if true;
      allow write: if getRole('admin') == true;
    }
    match /users/{userId}{
      allow read: if  request.auth.uid != null;
      allow create: if getRole('admin') == true ||  request.auth.uid == userId  &&
            !(getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny(["admin"]));
      allow update: if getRole('admin') == true ||  request.auth.uid == userId  && exists(/databases/$(database)/documents/users/$(request.auth.uid)) == true && !(getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny(["admin"]));
      }
  }
}

1 个答案:

答案 0 :(得分:0)

事实证明,除非我使用match /{document=**}(将这些规则应用于所有路径而不是所期望的结果),否则不允许管理员动态创建未在安全规则中定义的集合。我能够通过规则设置轻松完成其他部分,如下所示:

service cloud.firestore {
  match /databases/{database}/documents {
   function getRole(role) {
    return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
  }
    match /users/{userId} {
      allow read: if request.auth.uid != null;
      allow create: if request.auth.uid == userId && request.resource.data.roles.hasAny(["admin"]) == false;
    }
    match /collectionName/{collectionNameId} {
      allow read: if request.auth.uid != null;
      allow write: if request.auth.uid != null && getRole('admin') == true;
    }
  }
}