Dan*_*ván 4 firebase firebase-security firebase-realtime-database
也许我从SQL的角度来解决这个问题太多了,但是我很难理解如何正确地限制哪些孩子应该被允许填充节点.
假设我想保留具有任意名称的产品记录.每个产品必须包含一个price,但不允许任何其他产品.
我天真的方法是向.validate需要newData来包含price子price节点的产品添加规则,显式授予对节点的写访问权限,然后删除对节点的所有访问$other(有点像switch语句中的default子句):
{
"rules": {
"$product": {
".read": true,
".write": true,
".validate": "newData.hasChildren(['price'])",
"price": {
".write": true,
".validate": "newData.isNumber()"
},
"$other": {
".read.": false,
".write": false,
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用.{"price": 1234, "foo": "bar"}仍然会接受添加新产品.但是,如果我添加 (不管怎样,我做错了.)".validate": false规则$other,{"price": 1234}则不接受任何内容(例如,不允许).
有没有办法实现类似于我在这里尝试的东西?如果没有,在Firebase中限制数据结构的正确方法是什么?我应该这样做吗?如果我不这样做,是什么阻止用户用垃圾填充我的数据库?
您将在这里遇到一些常见的Firebase安全漏洞.最常见的是权限级联:一旦您在树中的某个级别上授予了读取或写入权限,就不能在较低级别上取消该权限.
这意味着这些规则是无效的(因为您已经将读/写权限提高了一级):
"$other": {
".read.": false,
".write": false,
}
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您必须意识到.validate规则是不同的:只有在满足所有验证规则时,数据才被视为有效.因此,您可以$other使用验证规则拒绝数据:
{
"rules": {
"$product": {
".read": true,
".write": true,
".validate": "newData.hasChildren(['price'])",
"price": {
".validate": "newData.isNumber()"
},
"$other": {
".validate": false
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |