Firebase安全规则:限制只写入此uid,但有几个字段除外

时间:2017-05-16 10:47:13

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

在Firebase中,我有一个users"节点",它看起来像:

users: {
  someUid: {
    username: 'someUsername'
    activeConversations: {},
    profile_picture: ''
    ... lots of other children
  },
  ...
},
anotherNode: {

},
... hundreds of other nodes

我现在的规则:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      ".indexOn": [
        "username"
      ]
    },
    "friendRequests": {
      ".indexOn": [
        "timeSent"
      ]
    }
  }
}

我想要做的是限制users"节点"中的儿童访问权限。只对拥有孩子的客户。因此,例如,someUid子项只能由具有uid someUid的客户端编写。其他"节点"像anotherNode这样的任何登录客户端都可以写/可读。 此外,任何已登录的客户端都应该能够在profile_picture文档中的activeConversationsusers上书写。

如何在不必在每个节点上放置读/写规则的情况下实现这一目标?

谢谢

3 个答案:

答案 0 :(得分:4)

在数据库的根目录中设置".read": true, ".write": true非常糟糕的想法。从字面上看,任何人都可以随时擦除整个数据库或插入任何数据。这是因为.read.write规则是级联的,因此如果您在某个节点对其进行评估true,则该人员也有该节点的所有子节点的权限。< /强>

幸运的是,更安全的规则,比如你提出的规则,很容易实现。我假设someUid等于您可以执行的用户auth.uid

{
  "rules": {
    "users": {
      ".indexOn": ["username"],
      // wildcard, matches any node under 'users'
      "$someUid": {
        ".read": "auth != null",
        ".write":"auth != null",
        "$other" : {
          ".validate": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid" // only that own user can change their username
        }
      }
    }
  }
}

我省略了你的friendRequests节点,因为我不确定你喜欢哪种安全规则,但我希望这足以让你开始。

Firebase docs很好地涵盖了这些内容。

答案 1 :(得分:4)

我认为@Bradley Mackey几乎就在那里,但只是需要一个小小的调整。

{
  "rules": {
    "users": {
      ".indexOn": ["username"],
      // wildcard, matches any node under 'users'
      "$someUid": {
        "$other" : {
          ".read": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
          ".write": "($other == 'profile_picture' || $other == 'activeConversations') || auth.uid == $someUid", 
        }
      }
    },
    "$anythingelse": {
      ".read": "auth != null",
      ".write": "auth != null",
    }
  }
}

".validate":字段可确保字段与特定格式匹配。如果字段是profile_picture或activeConversations,则此处的读取和写入应该为每个人提供读写访问权限,并允许用户访问其他所有内容。

编辑:

我添加了另一条规则,允许对任何非用户节点的任何已登录用户进行读写访问。

答案 2 :(得分:0)

根据firebase文档,您可以限制用户级别和数据级别的访问权限

例如,

    // These rules grant access to a node matching the authenticated
    // user's ID from the Firebase auth token
    {
      "rules": {
        "users": {
          "$uid": {
            ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid"
          }
        }
      }
    }

您还可以限制数据级别的读写权限,

{
  "rules": {
    "messages": {
      "$message": {
        // only messages from the last ten minutes can be read
        ".read": "data.child('timestamp').val() > (now - 600000)",

        // new messages must have a string content and a number timestamp
        ".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
      }
    }
  }
}

浏览这些firebase官方文档, https://firebase.google.com/docs/database/security/quickstart https://firebase.google.com/docs/database/security/user-security https://firebase.google.com/docs/database/security/securing-data