我目前正在使用$rootScope
来存储用户信息以及用户是否已登录。我尝试使用$window.localStorage
,但没有成功。我的目标是在用户登录后通过ng-show显示导航栏中的项目,用户名显示在导航栏中,个人用户个人资料视图,所有用户视图等等。我需要持久登录。我让导航栏使用$rootscope
,但每当我尝试转换到$window.localStorage
时,它都会失败。以下是使用$rootScope
的代码:
mainModule
angular.module('mainModule', [
'ui.router',
...
])
.config(configFunction)
.run(['$rootScope', '$state', 'Auth', function($rootScope, $state, Auth) {
$rootScope.$on('$stateChangeStart', function(event, next) {
if (next.requireAuth && !Auth.getAuthStatus()) {
console.log('DENY');
event.preventDefault();
$state.go('login');
} else if (Auth.getAuthStatus() || !Auth.getAuthStatus()) {
console.log('ALLOW');
}
});
}]);
Auth Factory
angular.module('authModule').factory('Auth', ['$http', '$state', function authFactory($http, $state) {
var factory = {};
var loggedIn = false;
var userData = {};
factory.getAuthStatus = function() {
$http.get('/api/v1/auth')
.success(function(data) {
if (data.status == true) {
loggedIn = true;
} else {
loggedIn = false;
}
})
.error(function(error) {
console.log(error);
loggedIn = false;
});
return loggedIn;
}
return factory;
}]);
登录控制器
function SigninController($scope, $rootScope, $http, $state) {
$scope.userData = {};
$scope.loginUser = function() {
$http.post('api/v1/login', $scope.userData)
.success((data) => {
$scope.userData = data.data;
$rootScope.loggedIn = true;
$rootScope.userData = data;
$state.go('home');
})
.error((error) => {
console.log('Error: ' + error);
});
};
}
导航控制器
function NavbarController($scope, Auth) {
$scope.loggedIn = Auth.getAuthStatus();
}
编辑编辑
以下是我使用本地存储的方式。这些是唯一改变的事情。
登录控制器
function SigninController($scope, $window, $http, $state) {
$scope.userData = {};
$scope.loginUser = function() {
$http.post('api/v1/login', $scope.userData)
.success((data) => {
$scope.userData = data.data;
$window.localStorage.setItem('userData', angular.toJson(data));
$window.localStorage.setItem('loggedIn', true);
$state.go('home');
})
.error((error) => {
console.log('Error: ' + error);
});
};
}
Auth Factory
angular
.module('authModule')
.factory('Auth', ['$http', '$window', '$state', function authFactory($http, $window, $state) {
var factory = {};
factory.getAuthStatus = function() {
$http.get('/api/v1/auth')
.success(function(data) {
if (data.status == true) {
$window.localStorage.setItem('loggedIn', true);
} else {
$window.localStorage.setItem('loggedIn', false);
}
})
.error(function(error) {
console.log(error);
$window.localStorage.setItem('loggedIn', false);
});
return $window.localStorage.getItem('loggedIn');
}
return factory;
}]);
答案 0 :(得分:2)
我发现您使用localStorage.getItem('loggedIn')
时可能存在问题。
因为localStorage只存储字符串,所以你得到的实际上是你输入的布尔值的字符串化版本。如果返回字符串'false'
,例如你在主模块中检查!Auth.getAuthStatus()
将始终评估为布尔false
,因为JavaScript中的任何非空字符串都是" truthy"。
即。 !'false' === false
(与!true === false
相同)
您可以通过对localStorage中的值使用JSON.parse来克服此问题。例如JSON.parse(localStorage.getItem('loggedIn'))
会将字符串'false'
解析为布尔值false
。
答案 1 :(得分:1)
只需将$window.localStorage
替换为window.localStorage
,您就可以了。
例如:
function SigninController($scope, $window, $http, $state) {
$scope.userData = {};
$scope.loginUser = function() {
$http.post('api/v1/login', $scope.userData)
.success((data) => {
$scope.userData = data.data;
window.localStorage.setItem('userData', angular.toJson(data));
window.localStorage.setItem('loggedIn', true);
$state.go('home');
})
.error((error) => {
console.log('Error: ' + error);
});
};
}
这就是说,在localStorage(或sessionStorage)中存储经过身份验证的状态并不是一条很好的路径。可以在开发人员窗格中读取键/值对,然后通过控制台更改(也称为欺骗)。更好的解决方案是在成功登录后返回唯一值(GUID)并将其存储在cookie中(设置为在短时间内过期,如20分钟),可以在服务器上读取并在那里进行验证。您可以而且应该使用$cookie
来实现此目的。您的用户登录状态应该在服务器端控制,而不是客户端控制。客户端应始终必须证明它已经过身份验证。
要保持登录,请创建一个处理访问者的服务,并让该服务处理登录/注销并提供登录证明。登录的证据应始终是由内部保存的私有值。服务,不在外面访问。
(function () {
'use strict';
var visitorModelService = ['$http', function ($http) {
var loggedIn = false,
visitorModel = {
login:function(){
//do login stuff with $http here
//set loggedIn to true upon success
},
loggedIn:function(){
return loggedIn;
},
logout:function(){
//do logout stuff with $http here
//no matter what, set loggedIn to false
}
};
return visitorModel;
}];
var module = angular.module('models.VisitorModel', []);
module.factory('VisitorModel', visitorModelService);
}());
执行此操作,您只需检查visitor.loggedIn
中的ng-show
并将所有内容集中在一起即可。如:
<a ng-click='visitor.logout' ng-show='visitor.loggedIn'>Log Out</a>
更好的是,将只有经过身份验证的用户可见的元素放在div
标记中,然后隐藏/显示它们。