Firebase:根据用户角色设置安全规则

时间:2014-09-03 09:48:11

标签: firebase firebase-security

我想根据用户角色在Firebase中实施“编写”安全规则 我的数据结构是这样的:

+ myapp
  + users
    + john
      + email: "john@mail.com"
      + roles
        + administrator: true
    + mary
      + email: "mary@mail.com"
      + roles
        + moderator: true
    + ...
  + documents
    + -JVmo6wZM35ZQr0K9tJu
      + ...
    + -JVr56hVTZxlAI5AgUaS
      + ...
    + ...

我希望 - 例如 - 只有管理员用户才能写文档 这些是我来的规则:

{
  "rules": {
    ".read": true,
    "$documents": {
      ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
    }
  }
}

但它不起作用:甚至管理员用户都不能写文件......
我对Firebase安全规则的理解是否完全有缺陷?

更新 : 就在Jenny回答之前(不管你信不信:-),我确实实现了他提供的完全相同的解决方案(当然基于Kato的评论)。
虽然,做了一些测试,我不能让规则结构

{
  "rules": {
    "documents" {
      "$document" {
        ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
        ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
      }
    }
  }
}

工作......我总是收到这样的警告:

"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "

所以我想出了这个结构,而不是:

{
  "rules": {
    "documents" {
      ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
      ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
    }
  }
}

对我来说确实有效:如果我将一个角色/ customers / read节点设置为true,他可以读取所有文档,否则他不能(和写入相同)。

我现在的怀疑是:

  • 为什么我不能让第一条规则(如加藤建议的那样)有效?
  • 您是否看到规则中存在任何可能的安全漏洞,就像我提出的那样?
  • 是使用“$”变量必要/有用的规则,即使您不必允许/拒绝每个单元的可读性/可写性 文档基于它的关键,但你只想允许/否认 整个节点的可读性/可写性?

1 个答案:

答案 0 :(得分:27)

根据您的用户记录的名称,它们不匹配auth.uid,这可能是Simple Login ID,例如twitter:2544215

首先通过简单登录uid调整您的用户存储:

+ myapp
  + users
    + twitter:2544215
      + email: "john@mail.com"
      + roles
        + administrator: true
    + twitter:2544216
      + email: "mary@mail.com"
      + roles
        + moderator: true
    + ...
  + documents
    + -JVmo6wZM35ZQr0K9tJu
      + ...
    + -JVr56hVTZxlAI5AgUaS
      + ...
    + ...

接下来,添加安全规则,以便管理员可以访问documents。这里有几个选项,具体取决于您的具体用例。

  1. 为管理员提供对每个文档内容的写访问权:

    {
      "rules": {
        "documents": {
          "$documents": {
            ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
          }
        }
      }
    }
    
  2. 或者,让他们访问整个集合:

    {
      "rules": {
        "documents": {
          ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
        }
      }
    }
    
  3. 这两者之间的差异是$documents变量,它将安全规则进一步移动到层次结构中。

    (这主要只是@Kato对答案形式的评论汇总)