强制执行与火力地堡simplelogin唯一的用户名 [英] Enforcing unique usernames with Firebase simplelogin

查看:121
本文介绍了强制执行与火力地堡simplelogin唯一的用户名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在遵循 Thinkster 教程在创建Web应用程序中使用角度和火力地堡。

I have recently followed a tutorial over on Thinkster for creating a web app using Angular and Firebase.

本教程使用火力地堡simpleLogin方法允许资料来创建一个包括用户名。

The tutorial uses the Firebase simpleLogin method allows a 'profile' to be created that includes a username.

厂址:

app.factory('Auth', function($firebaseSimpleLogin, $firebase, FIREBASE_URL, $rootScope) {
var ref = new Firebase(FIREBASE_URL);


var auth = $firebaseSimpleLogin(ref);

var Auth = {
    register: function(user) {
       return auth.$createUser(user.email, user.password);
    },
    createProfile: function(user) {
        var profile = {
            username: user.username,
            md5_hash: user.md5_hash
        };

        var profileRef = $firebase(ref.child('profile'));
        return profileRef.$set(user.uid, profile);
    },
    login: function(user) {
        return auth.$login('password', user);
    },
    logout: function() {
        auth.$logout();
    },
    resolveUser: function() {
        return auth.$getCurrentUser();
    },
    signedIn: function() {
        return !!Auth.user.provider;
    },
    user: {}
};

$rootScope.$on('$firebaseSimpleLogin:login', function(e, user) {
    angular.copy(user, Auth.user);
    Auth.user.profile = $firebase(ref.child('profile').child(Auth.user.uid)).$asObject();

    console.log(Auth.user);
});
$rootScope.$on('$firebaseSimpleLogin:logout', function() {
    console.log('logged out');

    if (Auth.user && Auth.user.profile) {
        Auth.user.profile.$destroy();
    }
    angular.copy({}, Auth.user);
});

return Auth;
});

控制器:

$scope.register = function() {
    Auth.register($scope.user).then(function(user) {
        return Auth.login($scope.user).then(function() {
            user.username = $scope.user.username;
            return Auth.createProfile(user);
        }).then(function() {
            $location.path('/');
        });
    }, function(error) {
        $scope.error = error.toString();
    });
};

在本教程的最后有一个下一步部分,其中包括:

At the very end of the tutorial there is a 'next steps' section which includes:

强制用户名uniqueness--这是一个棘手,检查出火力地堡的优先事项,看看你是否可以使用它们通过用户名查询用户配置文件

Enforce username uniqueness-- this one is tricky, check out Firebase priorities and see if you can use them to query user profiles by username

我已经搜查,搜查,但找不到如何做到这一点,尤其是在的 setPriority()火力地堡的功能

I have searched and searched but can't find a clear explanation of how to do this, particularly in terms of the setPriority() function of Firebase

我非常的火力地堡新手,所以这里的任何帮助将感激收到。

I'm quite the Firebase newbie so any help here would be gratefully recieved.

有几<一href=\"http://stackoverflow.com/questions/25294478/how-do-you-$p$pvent-duplicate-user-properties-in-firebase\">similar问题,但我似乎不能让我围绕如何排序了这一点头。

There are a few similar questions, but I can't seem to get my head around how to sort this out.

提前巨大的感谢。

修改

从Marein的答案,我已经更新了寄存器功能在我的控制器:

From Marein's answer I have updated the register function in my controller to:

$scope.register = function() {

    var ref = new Firebase(FIREBASE_URL);
    var q = ref.child('profile').orderByChild('username').equalTo($scope.user.username);
    q.once('value', function(snapshot) {
        if (snapshot.val() === null) {
            Auth.register($scope.user).then(function(user) {
                return Auth.login($scope.user).then(function() {
                    user.username = $scope.user.username;
                    return Auth.createProfile(user);
                }).then(function() {
                    $location.path('/');
                });
            }, function(error) {
                $scope.error = error.toString();
            });
        } else {
            // username already exists, ask user for a different name
        }
    });
};

但它抛出一个undefined是不是一个函数在该行变种Q = ref.child('个人资料')错误。orderByChild(用户名)。equalTo($ scope.user .username); 。我已经后注释掉code和尝试了CONSOLE.LOG(Q),但仍然没有喜悦。

But it is throwing an 'undefined is not a function' error in the line var q = ref.child('profile').orderByChild('username').equalTo($scope.user.username);. I have commented out the code after and tried just console.log(q) but still no joy.

编辑2

与上面的问题是,Thinkster教程使用火力地堡0.8 orderByChild只有在以后的版本可用。更新Marein的答案是完美的。

The issue with the above was that the Thinkster tutorial uses Firebase 0.8 and orderByChild is available only in later versions. Updated and Marein's answer is perfect.

推荐答案

有两件事情在这里做,客户端检查和服务器端的规则。

There are two things to do here, a client-side check and a server-side rule.

在客户端,你要检查用户名是否已经存在,这样就可以告诉用户,他们的投入是无效的,其发送到服务器之前。确切位置在哪里你实现这个给你,但code会是这个样子:

At the client side, you want to check whether the username already exists, so that you can tell the user that their input is invalid, before sending it to the server. Where exactly you implement this up to you, but the code would look something like this:

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控制台什么服务器呢?以prevent为此,你需要服务器端的安全性。

You can use this to check before writing to the server. However, what if a user is malicious and decides to use the JS console to write to the server anyway? To prevent this you need server-side security.

我试图想出一个例子解决方案,但我遇到了一个问题。希望有人更了解会一起去。我的问题如下。比方说,你的数据库结构如下所示:

I tried to come up with an example solution but I ran into a problem. Hopefully someone more knowledgeable will come along. My problem is as follows. Let's say your database structure looks like this:

{
  "profiles" : {
    "profile1" : {
      "username" : "Nick",
      "md5_hash" : "..."
    },
    "profile2" : {
      "username" : "Marein",
      "md5_hash" : "..."
    }
  }
}

在添加新的配置文件,你会希望有一个规则,确保具有相同用户名属性不存在配置文件对象。不过,据我所知火力地堡安全语言不支持这一点,这个数据结构。

When adding a new profile, you'd want to have a rule ensuring that no profile object with the same username property exists. However, as far as I know the Firebase security language does not support this, with this data structure.

一个解决办法是改变数据结构使用用户名为每个配置文件(而不是配置文件1 的关键, PROFILE2 ,...)。这种方式有永远只能是与该用户名一个对象,自动。数据库结构将是:

A solution would be to change the datastructure to use username as the key for each profile (instead of profile1, profile2, ...). That way there can only ever be one object with that username, automatically. Database structure would be:

{
  "profiles" : {
    "Nick" : {
      "md5_hash" : "..."
    },
    "Marein" : {
      "md5_hash" : "..."
    }
  }
}

这可能是在这种情况下,一个可行的解决方案。但是,如果不仅是用户名,但例如什么也电子邮件必须是唯一的?他们不能同时是对象键(除非我们使用字符串连接...)。

This might be a viable solution in this case. However, what if not only the username, but for example also the email has to be unique? They can't both be the object key (unless we use string concatenation...).

想到的是,除了配置文件列表,保持用户名的单独列表和电子邮件的单独列表,以及一件事。那么这些可以在安全规则很容易用来检查给定的用户名和邮件是否已经存在。该规则将是这个样子:

One more thing that comes to mind is to, in addition to the list of profiles, keep a separate list of usernames and a separate list of emails as well. Then those can be used easily in security rules to check whether the given username and email already exist. The rules would look something like this:

{
  "rules" : {
    ".write" : true,
    ".read" : true,
    "profiles" : {
      "$profile" : {
        "username" : {
          ".validate" : "!root.child('usernames').child(newData.val()).exists()"
        }
      }
    },
    "usernames" : {
      "$username" : {
        ".validata" : "newData.isString()"
      }
    }
  }
}

不过,现在我们遇到的另一个问题;如何确保创建一个新的配置文件时,用户名(和电子邮件)也放在这些新的名单? [1]

这反过来又可以通过利用配置文件创建code OUT的客户端,并把它的服务器上,而不是得到解决。然后,客户端需要向服务器创建一个新的配置文件,服务器将确保所有必要的任务的执行。

This in turn can be solved by taking the profile creation code out of the client and placing it on a server instead. The client would then need to ask the server to create a new profile, and the server would ensure that all the necessary tasks are executed.

但是,似乎很远,我们已经下降了一个洞来回答这个问题。也许我忽略了的东西,事情比他们似乎更简单。任何想法是AP preciated。

However, it seems we have gone very far down a hole to answer this question. Perhaps I have overlooked something and things are simpler than they seem. Any thoughts are appreciated.

另外,道歉,如果这个答案是更像是一个比回答的问题,我是新来的SO和还无法确定什么是适当的答案。

Also, apologies if this answer is more like a question than an answer, I'm new to SO and not sure yet what is appropriate as an answer.

<子> [1]虽然也许你可以认为这并不需要得到保证,因为恶意用户只通过不要求他们的独特身份害了自己?

这篇关于强制执行与火力地堡simplelogin唯一的用户名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆