【发布时间】:2014-08-30 14:37:37
【问题描述】:
我正在使用 roder 中的主干.js 编写一个应用程序来学习。你可以在这里找到我实际得到的:https://the-todo-app.firebaseapp.com/
我的想法是允许人们使用 simpleLogin 和 facebook 在应用程序中注册以创建用户,然后他们被重定向到他们的用户并被允许创建和修改他们的待办事项,但我遇到的问题是实际上每个用户都有可以在用户文件夹上写入,这意味着他们可以输入、删除或修改其他用户的数据。我想限制 firebase 的安全性,以允许他们根据他们的 id 创建用户,但如果他们没有经过身份验证,则不允许他们写。这是我实际拥有的:
{
"rules": {
".read": true,
".write": true,
".validate": "data.hasChildren(['name', 'picture'])",
"users": {
"$user": {
".read": "$user == auth.id",
".write": "$user == auth.id"
}
}
}
}
阿苏试过这个:
{
"rules": {
".read": true,
"users": {
"$user": {
".read": "$user == auth.id",
".write": "$user == auth.id"
}
}
}
}
但这种方法不允许客户端创建用户 ID。
这是我的数据的实际外观:
{
"users" : {
"10152111176005069" : {
"name" : "Jhonnatan Gonzalez Rodriguez",
"picture" : "url to pic"
},
"10154397958535078" : {
"name" : "Diana Rincón P",
"picture" : "url to pic"
},
"10152167159946759" : {
"name" : "Sebastian Ayala",
"picture" : "url to pic"
}
},
"title" : "The todo app"
}
如果你们知道如何做到这一点,我将不胜感激。
根据 ArneHugo 的回答,我刚刚设置了这个规则,并且看起来效果很好,我需要做更多的测试才能确定。
{
"rules": {
"users": {
".write": "!data.child(auth.id).exists()",
"$user": {
".read": "$user == auth.id",
".write": "$user == auth.id",
".validate": "newData.hasChildren(['name', 'picture'])"
}
}
}
}
我实际上必须将用户的 .read 规则添加到 true 以允许他们检查数据是否存在,这就是规则现在的样子。
{
"rules": {
"users": {
".read": "true",
".write": "!data.child(auth.id).exists()",
"$user": {
".read": "$user == auth.id",
".write": "$user == auth.id",
".validate": "newData.hasChildren(['name', 'picture'])"
}
}
}
}
这就是输出查找匿名用户的方式
Attempt to write {"id":"6726363"} to /users/6726363 with auth=null
/
/users:.write: "!data.child(auth.id).exists()"
5:30: child() expects a string argument.
=> false
/users/6726363:.write: "$user == auth.id"
=> false
/users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
=> false
Validation failed.
Write was denied.
这就是寻找经过身份验证的用户的方式。
Attempt to write {"name":"6726363","picture":"fb picture"} to /users/6726363 with auth={"id":"6726363"}
/
/users:.write: "!data.child(auth.id).exists()"
=> true
/users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
=> true
/users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
=> true
Write was allowed.
这是匿名尝试写入另一个用户数据的 uoutput。
Attempt to write {"name":"6726363","picture":"fb picture"} to /users/10152111176005069 with auth=null
/
/users:.write: "!data.child(auth.id).exists()"
5:30: child() expects a string argument.
=> false
/users/10152111176005069:.write: "$user == auth.id"
=> false
/users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
=> true
No .write rule allowed the operation.
Write was denied.
现在,做这个例子发现一个在数据库中已经存在 id 的经过身份验证的用户可以像这样写入另一个用户的数据。
Attempt to write {"name":"6726363","picture":"fb picture"} to /users/10152111176005069 with auth={"id":"6726363"}
/
/users:.write: "!data.child(auth.id).exists()"
=> true
/users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
=> true
/users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
=> true
Write was allowed.
【问题讨论】:
-
你看过anonymous auth吗?这可能是比不安全且可能是 hacky 的写入规则更好的解决方案。
-
@Kato 我认为问题在于,如果我设置匿名身份验证,用户将在顶层拥有写入权限,这意味着每个经过身份验证的用户都可以在用户/路径,因为已经过身份验证....我无法为此设置嵌套安全规则这一事实遇到了很大的问题
-
安全规则级联。如果您允许在 root 下写入,则用户可以在 root 下的任何级别写入。如果您想将它们限制在自己的路径中,请删除根目录下的规则。
-
@Kato 但如果我在用户未注册的情况下删除顶层的 wrtie,它将无法在数据库上创建其 uder:/
-
根级别的写入权限允许任何用户在不登录的情况下编辑任何数据。使用不同的解决方案。用户通常需要在编写新配置文件之前使用 createUser() 和 login() 创建身份验证令牌。
标签: javascript backbone.js firebase firebase-security firebasesimplelogin