我一直在为我的Firebase数据库设置规则,我注意到所有验证错误,无论是.write
还是.validate
,都会返回通用的Permission Denied错误。
来自this Google groups thread,这似乎是故意的
如果有更多描述性错误消息,则会泄露有关您的安全规则的信息
在我使用的大多数ORM中,例如ActiveRecord,Datamapper,Sequelize和Ecto,都能够返回保存失败原因的信息。
我从概念上理解,制作我自己的验证层并不是很困难,但它是死记硬背,需要我做一些我不想做的事情:
所以这个问题并不缺乏代码,这里是我的规则文件和客户端代码的片段:
规则:
{
"users": {
"$uid": {
".validate": "
(!data.exists())
",
".write": "
($uid === auth.uid)
",
".read": "
(auth != null)
"
},
},
}
从客户端保存记录(coffeescript):
store_user: (user) => new Promise (resolve, reject) => (->
key = @build_user_key(user)
@db.set(key, @build_user_data(user))
.then => resolve()
.catch (e) =>
window.error = e
).apply app
如果我运行此命令,请检查控制台中window.error
的值,我看到了:
error
Error: PERMISSION_DENIED: Permission denied
at bundle.js:3868
at fc (bundle.js:3707)
at Ah (bundle.js:3868)
at bundle.js:3863
at bundle.js:3825
at Ag.g.wd (bundle.js:3826)
at og.wd (bundle.js:3816)
at Yf.Xf (bundle.js:3814)
at ag (bundle.js:3798)
at WebSocket.Ia.onmessage (bundle.js:3797)
在这种情况下,我确信".validate": "(!data.exists())"
是导致失败的原因,因为我正在尝试创建已存在的用户。但是在我尝试创建它之前,我没有办法将这些知识反映到我的客户端Javascript而没有查找记录。
在每次保存之前查看记录真的是最佳选择吗?我听说人们应该“永远不要相信客户”,而且客户肯定会通过查看源代码来推断我的数据库结构。另一方面,我认识到有些情况下泄漏数据库细节很糟糕,例如,如果我有一个管理员电子邮件列表,我不想泄露它们。