限制用户对Firebase节点的读/写访问权限不起作用

时间:2019-01-23 17:50:08

标签: javascript firebase-realtime-database vuejs2 firebase-security-rules

我有一个具有几个根节点的firebase数据库结构(对于这个问题,只有几个很重要):建筑物 buildingsUserId buildingsUserUid的意图是为了控制用户只能访问其建筑物及其建筑物)。

如果我们更深入地研究两个节点的结构,则会得到以下内容:

users
  `-- userID // one user can access this 
  |   `-- isAdmin
  |       `-- building pushkey
  |       `-- another building pushkey etc.
  `-- another userID // one user can access this 
  |   `-- isAdmin
  |       `-- building pushkey
  |       `-- another building pushkey etc.
  `-- another user UID etc.


buildingsUserUid
  `-- firebase user UID // one user can access this 
  |   `-- building pushkey
  |   `-- another building pushkey
  `-- another firebase user UID // another user can access this 
      `-- yet another building pushkey 
      `-- and another building pushkey etc.

buildings
 `-- building pushkeys // user with right UID can access this
 |   |-- firebase user UID
 |   `-- Other data
 `-- building pushkeys  //another user with right UID can access this
     |-- firebase user UID
     `-- Other data

然后我的Firebase规则如下:

{
  "rules": {
      "users": {
          "$uid": {
            ".read": "auth.uid == $uid",
            ".write": "auth != null && $uid === auth.uid",
          }
      },
      "buildings": {
         ".read": "root.child('buildingsUserUid').hasChild(auth.uid)",
         ".write": "!data.exists() || root.child('buildingsUserUid').hasChild(auth.uid)",
            "$pushkey": {
                ".read": "root.child('buildingsUserUid').child(auth.uid).hasChild($pushkey)",
                ".write": "!data.exists() || root.child('buildingsUserUid').child(auth.uid).hasChild($pushkey)",
             }
      },
      "buildingsUserUid": {
         "$user": {
             ".read": "auth != null && auth.uid === $user",
             ".write": "auth != null && auth.uid === $user"
          }
      },
 }

使用上述规则,我希望将对建筑物节点的访问限制为仅在其buildingsUserUid节点上具有建筑物按键的用户。但是,如果我在vue.js应用程序上 console.log(this),我可以看到所有建筑物。

enter image description here

这是因为我要从应用程序登录,还是用户可以通过浏览器控制台以相同的方式访问?我在规则中遗漏了什么吗?

更新:

在@Umar回答之后,我将规则更改为:

{
  "rules": {
      "users": {
          "$uid": {
            ".read": "auth.uid == $uid",
            ".write": "auth != null && $uid === auth.uid",
          }
      },
      "buildings": {
         ".read": "root.child('buildingsUserUid').hasChild(auth.uid)",
         ".write": "!data.exists() || root.child('buildingsUserUid').hasChild(auth.uid)",
            "$pushkey": {
                // changed the following 'read' rule line
                ".read": "root.child('buildingsUserUid').child($pushkey).child('userId') === auth.uid"
                ".write": "!data.exists() || root.child('buildingsUserUid').child(auth.uid).hasChild($pushkey)",
             }
      },
      "buildingsUserUid": {
         "$user": {
             ".read": "auth != null && auth.uid === $user",
             ".write": "auth != null && auth.uid === $user"
          }
      },
 }

但这会触发错误:

  

错误保存规则-第15行:无效==表达式:左操作数不是数字,布尔值,字符串,空值。 –

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

通过将".read": "root.child('buildingsUserUid').hasChild(auth.uid)"放到buildings,您实际上是在允许任何建筑物的任何用户读取所有建筑物节点数据。

您必须允许读访问权限位于下一级,即pushkey下。另外,如果您仅将一个用户与一栋建筑物相关联,则只需将建筑物ID存储在用户节点下,而不是在建筑物的按键下即可。

对于您当前的结构pushkey读为

".read": "root.child('buildingsUserUid').child($pushkey).child('userId') === auth.uid"

我假设您每个建筑物有一个用户,并且用户的uid与键userId存储在“ pushkey”下