我目前正在使用$rootScope存储用户信息,以及用户是否已登录。我试过使用$window.localStorage,但没有成功。我的目标是让我的导航栏中的项目在登录后通过ng显示出现,让他们的用户名出现在导航栏、个人用户配置文件视图、所有用户视图等。我需要一个持久的登录。我让navbar使用$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工厂
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);
});
};
}Nav控制器
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工厂
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;
}]);发布于 2016-11-15 21:24:52
在使用localStorage.getItem('loggedIn')时,我发现了一个潜在的问题。
因为localStorage只存储字符串,所以返回的实际上是放入的布尔值的字符串版本。例如,如果返回字符串'false',则主模块中的!Auth.getAuthStatus()检查将始终计算为布尔false,因为JavaScript中的任何非空字符串都是“真实的”。
即!'false' === false (与!true === false相同)
您可以通过对JSON.parse中的值使用localStorage来克服这一问题。例如,JSON.parse(localStorage.getItem('loggedIn'))将将字符串'false'解析为布尔false。
发布于 2016-11-15 21:56:56
只需将$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);
}());这样做,您可以简单地在您的ng-show中检查是否有ng-show,并将所有内容集中起来。例如:
<a ng-click='visitor.logout' ng-show='visitor.loggedIn'>Log Out</a>更好的是,将只对经过身份验证的用户可见的元素放在一个div标记中,然后隐藏/显示它们。
https://stackoverflow.com/questions/40619135
复制相似问题