我正在使用FirebaseSimpleLogin创建用户并处理身份验证。
当我尝试通过$ createUser()方法创建一个新的用户,通过简单的登录,如果电子邮件地址已被使用,firebase将不会创建用户。不过,我也在使用$ set()将创建的用户保存到我的firebase中,我创建它们之后,我使用user.uid作为关键。当尝试写入数据库时,即使用户名不唯一,firebase也会保存记录,因为只需要电子邮件和密码才能进行简单的登录。那么当用户对象不被用作键的时候,怎样验证用户名是唯一的?
我正在创建这样的新用户:
$scope.createUser = function() { $scope.auth.$createUser('trinker@gmail.com','password').then(function(user,err) { if (!err) { ref.child('users/' + user.uid).set({ email: user.email,username: user.username }); console.log("success!"); }else{ console.log(err.message); } }); }
我的用户对象如下所示:
{ "users" : { "simplelogin:28" : { "email" : "trinker@gmail.com","username" : "jtrinker" },"simplelogin:30" : { "email" : "test@gmail.com","username" : "jtrinker" } } } }
首先,如果用户已经有用户名,它是唯一的,这不会消失,我建议你放弃使用简单的登录uid。这将会创造出任何事情,试图在两者之间来回移动,正如你已经在这里发现的那样。用
firebase-passport-login这样的工具调查
creating your own tokens,然后用用户名存储记录。
但是,既然这不是你的问题,我们来解决这个问题,因为我们在这里,因为你可能想要进入我经过很多次的双重身份的棘手之王。
/用户/ $用户名/用户名/ $的用户名
/用户名/ $的用户名/ $用户ID
为了确保它们是唯一的,请在usernames / path中的用户标识中添加以下安全规则,这样可以确保每个用户名只能分配一个用户,并且该值是用户的ID:
".write": "newData.val() === auth.uid && !data.exists()"
"users": { "$userid": { "username": { ".validate": "root.child('usernames/'+newData.val()).val() === $userid" } } }
这将确保ids是唯一的。小心阅读权限。您可能希望完全避免这些,因为您不希望任何人查找私人电子邮件或用户名。 Something like I demonstrated in support保存这些将是理想的。
这里的想法是,您尝试分配用户名和电子邮件,如果它们失败,那么它们已经存在并属于另一个用户。否则,您将它们插入到用户记录中,现在有用户通过uid和电子邮件索引用户。
var fb = new Firebase(URL); function escapeEmail(email) { return email.replace('.',','); } function claimEmail(userId,email,next) { fb.child('email_lookup').child(escapeEmail(email)).set(userId,function(err) { if( err ) { throw new Error('email already taken'); } next(); }); } function claimUsername(userId,username,next) { fb.child('username_lookup').child(username).set(userId,function(err) { if( err ) { throw new Error('username already taken'); } next(); }); } function createUser(userId,data) { claimEmail(userId,data.email,claimUsername.bind(null,userId,data.username,function() { fb.child('users').child(userId).set(data); ); }
规则:
{ "rules": { "users": { "$user": { "username": { ".validate": "root.child('username_lookup/'+newData.val()).val() === auth.uid" },"email": { ".validate": "root.child('email_lookup').child(newData.val().replace('.',')).val() === auth.uid" } } },"email_lookup": { "$email": { // not readable,cannot get a list of emails! // can only write if this email is not already in the db ".write": "!data.exists()",// can only write my own uid into this index ".validate": "newData.val() === auth.uid" } },"username_lookup": { "$username": { // not readable,cannot get a list of usernames! // can only write if this username is not already in the db ".write": "!data.exists()",} }