Firebase:根据用户角色设置安全规则 [英] Firebase: set security rules depending on user roles

查看:109
本文介绍了Firebase:根据用户角色设置安全规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据用户角色在Firebase中实现写入安全规则。

我的数据结构如下所示:

<$ p $ + myapp
+用户
+ john
+ email:john@mail.com
+角色
+ administrator:true
+ mary
+ email:mary@mail.com
+角色
+版主:true
+ ...
+文件
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...

我想要 - 例如 - 只有管理员用户可以写文件。

这些是我得到的规则:


$ b $

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





但它不起作用:不是前夕n个管理员用户可以写文档...

b $ b我对Firebase安全规则的理解完全有缺陷吗?

UPDATE
在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
}
}
}
}

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

<$ p $ / p> FIREBASE WARNING:on()or once()for / documents failed:Error:permission_denied:Client d没有权限访问所需的数据。

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

  {
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
}




$ b $ p
$ b

对我来说,确实有效:如果我设置角色/客户/阅读节点为真的用户,他可以阅读所有文件,否则他不能(同样写)。

我现在怀疑的是:为什么我不能让第一条规则(如Kato所建议的)有效?

  • 你知道吗?任何可能的安全漏洞,像我所做的规则一样?

  • 是使用$变量必要/有用的规则,即使您不必允许/拒绝可读性/可写性每个单一的
    文档基于它的关键,但你只是想允许/拒绝整个节点的
    的可读性/可写性?
    $ b $基于你的用户记录的名字,它们不匹配 auth.uid ,可能是一个简单登录标识,例如 twitter:2544215



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

      + myapp 
    +使用者
    + twitter:2544215
    +电子邮件:john@mail.com
    +角色
    +管理员:true
    + twitter:2544216
    + email:mary@mail.com
    +角色
    +主持人:true
    + ...
    + documents
    + -JVmo6wZM35ZQr0K9tJu
    + ...
    + -JVr56hVTZxlAI5AgUaS
    + ...
    + ...

    接下来, dd安全规则,以便管理员可以访问文档。您可以在这里选择一些选项,具体取决于您的特定用例。


    1. 让管理员可以访问每个文档的内容:

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




      $ c $ $ $ $ $ $或者,也可以让他们访问整个集合:

        {
      rules:{
      documents:{
      .write:root.child('users')。child(auth.uid).child('roles')。child('administrator')。val )=== true

      }
      }


    这两个变量之间的区别在于 $ documents 变量,它将安全规则进一步移动到层次结构中。



    (这大部分只是@Kato的意见汇总到答案表格中)

    I would like to implement "write" security rules in Firebase depending on users roles.
    My data structure is like this:

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

    I want - for example - that only administrator users can write documents.
    These are the rules I've come to:

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

    But it doesn't work: not even administrator users can write documents...
    Is my understanding of Firebase security rules totally flawed?

    UPDATE: Just before Jenny's answer (believe it or not :-), I did implement the exact same solution he provides (of course based on Kato's comment).
    Though, making some tests, I could not let the rules structure

    {
      "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"
          }
        }
      }
    }
    

    work... I always got a warning like this:

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

    So I came up with this structure, instead:

    {
      "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"
        }
      }
    }
    

    Which indeed works, for me: if I set a roles/customers/read node to true on a user he can read all documents, otherwise he can't (and the same for write).

    My doubts now are:

    • why I could not let the first rule (as suggested by Kato) work?
    • do you see any possible security hole in a rule like the one I did came up with?
    • are rules using "$" variables necessary/useful even if you don't have to allow/deny the readability/writeability of each single document based on it's key, but you just want to allow/deny the readability/writeability of a node as a whole?

    解决方案

    Based on the names of your user records, they don't match auth.uid, which is probably a Simple Login id, such as twitter:2544215.

    Start by adjusting your users to be stored by their Simple Login uid:

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

    Next, add a security rule so that administrators can access documents. You have a couple options here, depending on your specific use case.

    1. To give administrators write access to contents of each document:

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

    2. Or, alternatively, give them access to the whole collection:

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

    The difference between these two being the $documents variable that moves the security rule one step further into the hierarchy.

    (This was mostly just an aggregation of comments by @Kato into answer form)

    这篇关于Firebase:根据用户角色设置安全规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆