我正在尝试使用Firebase安全规则来防止在我的应用中发生许多不良情况。我目前的结构是:
"usernames": {
"twitter:123": "jack",
"google:456": "bob"
}
这里的问题是我无法实现安全规则,以至于第三个用户(比如facebook:789
)无法进入并劫持用户名'bob'并访问该用户的数据(我的数据)由用户名安排。
此方案的可接受修复是什么?我试过反转键/值对,这允许用户名的唯一性:
"usernames": {
"jack": "twitter:123",
"bob": "google:456"
}
然而,由于这不强制UID的唯一性,任何用户都可以垃圾邮件用户名 - 恶意facebook:789
可以使用任何尚未使用的用户名,这将是PITA的整理。
有没有办法使用Firebase安全规则解决这个难题?或者是受信任的服务器的唯一答案?可信服务器仍会出现可能的并发问题。
答案 0 :(得分:0)
好的,我想我已经知道了。像Firebase中的很多东西一样,答案在于勤奋使用非规范化:)
这个解决方案仍然是一个位暂定,所以如果你有更正或更好的想法,请不要犹豫,纠正/编辑/评论/回答。
用户名/ uid对需要以两种格式存储。由于缺少一个更好的名字,我称之为 interlock :
{
"usernameInterlock" : {
"confirm" : {
"twitter:123" : "jack"
},
"request" : {
"jack" : "twitter:123"
}
}
}
以下是安全规则:
{
"rules": {
"usernameInterlock": {
"request": {
"$username": {
".read": true,
".write": "auth.uid == newData.val()
&& !(
data.exists()
&& root.child('usernameInterlock').child('confirm').child(data.val()).val() == $username
)"
}
},
"confirm": {
"$uid": {
".read": true,
".write": "auth.uid == $uid
&& root.child('usernameInterlock').child('request').child(newData.val()).val() == auth.uid"
}
}
}
}
}
过程是:
uid
放入/usernameInterlock/request/$desiredUsername
。这是可写除非 /usernameInterlock/confirm/$uid_2 == $desiredUsername
,在这种情况下它属于$uid_2
。任何人都可以请求他们想要的任何用户名(无论他们想要多少),因为除非他们在confirm
之下,否则他们没有任何意义。如果某人太疯狂,可以将其清除。$desiredUsername
写入/usernameInterlock/confirm/$uid
。只有在已填充适当的request
子项时才能写入此内容。这将成为确定用户用户名的规范方式。要验证用户名,请先查找/usernameInterlock/request/$username
,然后查找$uid
中获得的/usernameInterlock/confirm/$uid
,如果该值与$ username匹配,则($username, $uid)
是有效对。