使用$location时,Firebase.validate未按预期工作



我有以下Firebase规则,并且我很难使验证按预期工作:

{
"rules": {
".read": true,
".write": true,
"specialItems": {
"$itemid": {
".validate": "root.child('items/' + $itemid).exists()"
}
}
}
}

我的.validate规则的意图是,"specialItems"列表中的条目只有在"items"列表中已经存在时才被接受。不幸的是,Firebase允许我无论如何都添加到specialItems中——毫无疑问,因为我误解了验证应该如何工作。

我使用应用程序引擎python-urlfetch API通过REST与firebase对话,并使用PATCH方法。

auth_payload = {"uid": "custom:1", "auth_data": "foo"}
token = create_token(FIREBASE_SECRET, auth_payload, {"admin": True})
url = "https:/<my-app>.firebaseio.com/specialItems.json?auth=" + token
payload = json.dumps({"myItem": "ok"})
result = urlfetch.fetch(url=url, payload=payload, method=urlfetch.PATCH)

当从一个空数据库开始时,这给我留下了一个完整的数据树,看起来像:

specialItems
-- myItem: "ok"

我原以为这棵树会通过验证规则。我也尝试过使用PUT,它具有相同的效果:

url = "https://<my-app>.firebaseio.com/specialItems/myItem.json?auth=" + token
result = urlfetch.fetch(url=url, payload='"ok"', method=urlfetch.PUT)

另一件需要注意的事情是,尽管我的规则似乎表明任何人都应该有读/写权限,但我目前需要使用"admin:True"进行身份验证才能写任何东西。这让我想知道我的规则是否被应用了——如果是这样的话,那么我不确定如何启用我的规则——它们就在"安全&"规则"窗格。在这里,我还假设管理员不允许违反模式验证规则。

您的假设不正确。使用admin: true进行身份验证将绕过安全规则。因此,您的.validate规则将不会应用于这种情况。.validate规则本身在物理上没有任何问题。

此外,假设您的问题准确地反映了实际情况,则此处不需要身份验证。根路径上的.write/.readtrue将允许访问Firebase中的任何数据。很可能,您的规则运行得很好,并且阻止了写入,这就是为什么您错误地认为需要admin: true来写入数据。

正如赛义德在回答中所建议的那样,一定要检查模拟器。

尝试以下代码

{
"rules": {
".read": true,
".write": true,
"specialItems": {
"$itemid": {
".validate": "root.child('items').hasChild($itemid)"
}
}
}
}

您可以使用仪表板上的模拟器来测试您的规则。如果不需要身份验证,请确保您已选中"启用匿名用户身份验证",进行身份验证,然后输入您的url并检查读写结果。

最新更新