这里有两件事要做,一个客户端检查和一个服务器规则。
在客户端,您需要检查用户名是否已经存在,以便在将用户名输入到服务器之前,可以告诉用户其输入无效。具体在哪里实现,但代码看起来像这样:
var ref = new Firebase('https://YourFirebase.firebaseio.com');var q = ref.child('profiles').orderByChild('username').equalTo(newUsername);q.once('value', function(snapshot) { if (snapshot.val() === null) { // username does not yet exist, go ahead and add new user } else { // username already exists, ask user for a different name }});您可以在写入服务器之前使用它进行检查。但是,如果用户是恶意的并且决定仍然使用JS控制台写入服务器怎么办?为防止这种情况,您需要服务器端安全性。
我试图提出一个示例解决方案,但遇到了一个问题。希望会有更多知识渊博的人来。我的问题如下。假设您的数据库结构如下所示:
{ "profiles" : { "profile1" : { "username" : "Nick", "md5_hash" : "..." }, "profile2" : { "username" : "Marein", "md5_hash" : "..." } }}添加新的配置文件时,您需要制定一条规则,以确保不
username存在具有相同属性的配置文件对象。但是,据我所知,Firebase安全语言不支持这种数据结构。
一个解决办法是改变数据结构使用
username的每个配置文件键(而不是
profile1,
profile2......)。这样,就只能自动有一个带有该用户名的对象。数据库结构为:
{ "profiles" : { "Nick" : { "md5_hash" : "..." }, "Marein" : { "md5_hash" : "..." } }}在这种情况下,这可能是一个可行的解决方案。但是,如果不仅用户名而且电子邮件必须唯一,该怎么办?它们不能同时是对象键(除非我们使用字符串串联…)。
除了配置文件列表之外,还要想到的另一件事是,还要保留一个单独的用户名列表和一个单独的电子邮件列表。然后可以轻松地将它们用于安全规则中,以检查给定的用户名和电子邮件是否已经存在。规则如下所示:
{ "rules" : { ".write" : true, ".read" : true, "profiles" : { "$profile" : { "username" : { ".validate" : "!root.child('usernames').child(newData.val()).exists()" } } }, "usernames" : { "$username" : { ".validate" : "newData.isString()" } } }}但是现在我们遇到了另一个问题。如何确保在创建新的配置文件时,用户名(和电子邮件)也被放入这些新列表中?[1]
反过来,可以通过将概要文件创建代码从客户端中取出并将其放置在服务器上来解决。然后,客户端将需要请求服务器创建新的配置文件,并且服务器将确保执行所有必需的任务。
但是,似乎我们已经很不容易回答这个问题了。也许我忽略了某些事情,而且事情比看起来简单。任何想法表示赞赏。
另外,如果这个答案更像是一个问题而不是答案,我深表歉意。我是SO的新手,不确定是否适合作为答案。
[1]尽管您可能会争辩说这并不需要得到保证,因为恶意用户只会通过不声明自己的唯一身份来伤害自己?



