Javascript Firebase安全规则:限制仅写入此uid,几个字段除外

Javascript Firebase安全规则:限制仅写入此uid,几个字段除外,javascript,firebase,firebase-realtime-database,firebase-security,Javascript,Firebase,Firebase Realtime Database,Firebase Security,在Firebase中,我有一个用户节点,它看起来像: users: { someUid: { username: 'someUsername' activeConversations: {}, profile_picture: '' ... lots of other children }, ... }, anotherNode: { }, ... hundreds of other nodes 我现在的规则是: { "rules": {

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

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"
      ]
    }
  }
}
我想做的是将child在
users
“节点”中的访问权限仅限于拥有该子节点的客户端。因此,例如,
someUid
子项应该只能由具有uid
someUid
的客户端写入。其他“节点”,如
另一个节点
,可以由任何登录的客户端写入/读取。 此外,任何登录的客户端都应该能够在
users
文档中的
profile\u picture
activeConversations
上书写

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

感谢您拥有
”。在数据库的根目录下读取:true,。写入: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
节点,因为我不确定你想要什么样的安全规则,但我希望这足以让你开始


这本书的封面非常好。

我认为@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\u picture或activeConversations,则此处的读写操作应为每个人提供读写访问权限,并为用户提供对其他所有内容的访问权限

编辑:


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

根据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官方文件,

谢谢你的布拉德利。对于
activeConversations
profile\u picture
,我如何保持对任何经过身份验证的用户的写入权限?对于
friendRequests
和其他节点,我们可以保持
write:true
read:true
。如果我们把它放在全局范围内,它会为所有节点级联(例如在
用户中设置它时,它会覆盖这些节点)@DanP。查看我的更新答案,也不要将它们设置为
true
,除非您非常明确地需要它。这是非常糟糕的做法,至少检查一下
auth!=空
。谢谢。除了用户名、个人资料、图片等,我实际上还有50个孩子。是否可以将默认设置为
auth!=null&&auth.uid=$someUid
,并将
profile\u picture
activeConversations
设置为
auth!=空值
?(基本上,将您在
username
下编写的规则与
$other
中的规则进行切换)@DanP。是的,你很容易做到!嗨,亚当。谢谢但是
用户
旁边的其他节点呢?默认情况下,如果未设置,则没有读/写访问权限。同一级别的
用户
的其他节点应该具有读/写访问权限。现在进行编辑,希望能够完成您想要的操作。回答得好。需要在“$anythingelse”
之前加一个逗号,谢谢Bob,他补充说我试过了,但不起作用,我不确定现在的陷阱在哪里,我正在调查它是否来自我自己的数据,例如除了
profile\u picture
activeConversations
之外的字段是否需要写/读访问。我一深入研究就会回来。