【发布时间】:2017-07-03 04:58:09
【问题描述】:
在我使用 Firebase 创建的 iOS 应用中,每个用户都有一个唯一的用户名,该用户名是在他们使用电子邮件和密码注册后创建的。
因此,如果一个用户的电子邮件是 test5@gmail.com,然后必须创建一个不在用户名数据库中的唯一用户名,那么数据库的 sn-p 将如下所示:
"usernames" : {
"test" : "r6KPesUr1qORfIJke07SloZHeNW2",
"test1" : "jSMSkY9rHtdNkXoLrsFmCAXdY9n2",
"test7" : "jnFhJbgCjZeJFx0hspObqoskQej2",
"test8" : "HtnULzU0lnZKYva2M2Wepl6N8wE3"
},
"users" : {
"HtnULzU0lnZKYva2M2Wepl6N8wE3" : {
"email" : "test8@gmail.com",
"username" : "test8"
},
"boX6rtJ98haWVxNoXfSq21maCVU2" : {
"email" : "test5@gmail.com"
},
"jSMSkY9rHtdNkXoLrsFmCAXdY9n2" : {
"email" : "Test1@gmail.com",
"username" : "test1"
},
"jnFhJbgCjZeJFx0hspObqoskQej2" : {
"email" : "test7@gmail.com",
"username" : "test7"
},
"r6KPesUr1qORfIJke07SloZHeNW2" : {
"email" : "test6@gmail.com",
"username" : "test"
}
}
我制定了以下安全规则,以确保用户完成注册后用户名是唯一的。
// USERNAMES
"usernames": {
".read": "auth.uid != null",
".write": "auth.uid != null",
"$username": {
".validate": "(!root.child('usernames').hasChild($username.toLowerCase()) && newData.val() == auth.uid &&
root.child('users').hasChild(auth.uid)) &&
(root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username ||
!root.child('users/'+auth.uid+'/username').exists())"
}
}
对于验证规则,我希望这三个语句必须具备
(!root.child('usernames').hasChild($username.toLowerCase()) &&
newData.val() == auth.uid &&
root.child('users').hasChild(auth.uid))
这两个陈述中的一个必须是正确的
"(root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username ||
(!root.child('users/'+auth.uid+'/username').exists()"
因此,如果用户想使用 test5 作为具有以下 json 的用户名进行注册,那么由于 OR 语句的第一部分,它将不适用于我当前的安全规则。
"users": {
"boX6rtJ98haWVxNoXfSq21maCVU2": {
"username": "test5"
}
}
我做错了什么?
【问题讨论】:
-
解析规则相当困难。您能否编辑您的问题以包含可能会被此验证规则拒绝但您希望允许的最少代码?
-
@FrankvanPuffelen 确定。我已经添加了数据库的外观以及随后无法写入的 json,以使用 test5@gmail.com 的电子邮件为用户创建唯一的用户名
-
好的。我试着弄清楚你的用例。但是从如此复杂的规则中理解起来很棘手,因此我分离了一个(以及两个)特定用例并专注于它。
-
@FrankvanPuffelen 你绝对又搞定了。那是我的确切用例。不知道还能说什么,但非常感谢。 Firebase 很棒
-
很高兴听到我猜对了爱德华。最近有很多安全规则问题,所以我的头越来越疼。 :-) 在 Firebase 上玩得开心!
标签: firebase firebase-realtime-database firebase-security