如果输入数据是一个由多个json对象组成的json对象,每个父节点(例如,每个用户)都具有无法预定义的唯一键,那么如何保护结构?
与示例相同的问题:
因此,假设用户将ID为E5435、59z195J,k311的3种食物标记为收藏:以下结构似乎可以。
{ fav: { $uid { "E5435":1, "59z195J":1, "k311":1 } } }
但是!如何防止结构随任意数据扩展?您可以添加验证规则来检查数据类型和长度等。但是子名称未定义,可以类似于上面的示例。
我不想保留1个长的收藏夹字符串,因为这意味着同步将无法部分进行,我必须覆盖数据并每次下载。
我无法添加所有可能的食物ID,因为它会使结构非常长,并且列表可能随时增加。
[在可能的输入是这样的情况下,如何添加规则以保护此结构:
/fav/UID1234567/ <-- {"AAAA5":1,"G545345":1,"D454WW":1}
([Notes:食物ID故意用混淆的字符书写。如果这样可以更轻松地分析问题,可以将其替换为名称。
[AAAA5 --> APPLE, D454WW --> RICE )
形成:/fav/UID1234567/ <-- {"APPLE":1,"RICE":1}
并且请记住,没有预定义的食物列表可供选择:因此,像[BANANA, APPLE, RICE, SUSHI,.....]
这样的nothing存在。该巨大列表存在但在Firebase之外。
当客户端完全下载/fav/USERID/
的内容(仅1次)时,它将比较整个列表与其他列表,以过滤这些项目并将其显示为收藏夹。
笔记结尾)
其他信息:要清楚,如何防止使用某些长文本而不是“ APPLE”,以及再次使用长文本而不是其值“ 1”。由于这些数据将增加基础火力成本,因此可以视为攻击。通常的验证规则似乎不起作用,因为在此示例中,我们不是将值逐1推送,而是将它们乘以1。因此,没有newData().children().key.isString()
和newData().children().key.length()
,etc ...
因此,如果您想限制最喜欢的食物节点的ID的长度,以及将此类节点的值强制为1
,则以下规则可以解决问题:
{
"rules": {
"fav": {
"$uid": {
"$foodid": {
".read": true,
".write": true,
".validate": "newData.isNumber() && newData.val() == 1 && $foodid.length < 5"
}
}
}
}
}
请注意,此规则仅适用于仅推送一个节点或多个节点。
您可以使用JS SDK尝试以下操作:
var database = firebase.database();
var updates = {};
updates['fav/user456/AAA5'] = 1;
updates['fav/user456/ABVD'] = 1
updates['fav/user123/YUIH'] = 1
database.ref().update(updates);