我努力让我的angularJS / Firebase应用程序中的用户身份验证工作了好几天,直到我终于开始工作了。问题是,我知道我提出的解决方案是非常黑客攻击,而不是正确的方法来进行身份验证。此外,登录似乎仅在用户点击登录按钮两次后才能工作。如果有人能够以正确的方式提供指导,我将不胜感激。
我已经阅读了与此问题相关的SO的一些答案,但它们对于我所需要的东西似乎都过于复杂。简而言之,如果用户登录,他或她应该能够访问应用程序中的任何视图。如果用户未登录并尝试访问需要身份验证的URL,则会将其发送回登录屏幕。我还需要能够在他或她登录后访问当前用户的ID。
我通过Firebase的简单登录使用电子邮件/密码身份验证。现在我正在使用AuthService在用户的身份验证状态发生变化时通知应用程序控制器(至少我认为我是)。如果用户已登录,我将userID保存在会话存储中,然后重定向到Epics Feed页面。然后我有一个用户服务从会话存储中提取userID。这是代码:
身份验证服务:
app.service('AuthService', function($rootScope, $location, $q, SessionService, angularFireAuth) {
var epiclyRef = new Firebase('my firebase ref');
this.auth = new FirebaseSimpleLogin(epiclyRef, function(error, user) {
if (error) {
$rootScope.$emit("loginError", error);
} else if (user) {
$rootScope.$emit("login", user);
} else {
$rootScope.$emit("logout");
}
});
});
登录控制器:
app.controller("LoginController", function($scope,$location, $rootScope, $window, AuthService, SessionService){
$scope.credentials = { email: "", password: "" };
$scope.login = function(){
AuthService.auth.login('password', {
email:$scope.credentials.email,
password: $scope.credentials.password
});
}
$rootScope.$on("login", function(event, user, $location) {
// do login things
var userId = user.id;
SessionService.set('authenticated', true);
SessionService.set('user', userId);
$window.location = '#/epicsFeed';
});
$rootScope.$on("loginError", function(event, error) {
// tell the user about the error
console.log(error);
});
})
用户从导航菜单注销,因此注销功能位于菜单控制器中:
app.controller('MenuController',function($scope,$location, $rootScope, $window, AuthService, SessionService){
$scope.logout = function() {
AuthService.auth.logout();
$rootScope.$on("logout", function(event, $location) {
// do logout things
SessionService.unset('authenticated');
SessionService.unset('user');
$window.location = '/';
})
};
})
并控制用户可以使用/不使用身份验证访问哪些视图:
app.run(function($rootScope, $location, SessionService){
var routesThatDontRequireAuth = ['/', '/register'];
$rootScope.$on('$routeChangeStart', function( event, next, current){
if(!_(routesThatDontRequireAuth).contains($location.path()) && !(SessionService.get('authenticated'))){
$location.path('/');
console.log("Please login to continue");
}
})
})