2016-11-15 66 views
2

我目前使用$rootScope存储用户信息以及用户是否登录。我尝试过使用$window.localStorage,但没有成功。我的目标是一旦用户登录,让他们的用户名出现在导航栏,个人用户配置文件视图,所有用户视图等中,我的导航栏中的项目通过ng-show显示。我需要持久登录。我有导航栏$rootscope,但每当我尝试转换到$window.localStorage时,它都会失败。下面是使用$rootScope代码:使用本地存储来存储AngularJS数据

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'); 
      } 
     }); 
    }]); 

验证厂

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); 
      }); 
    }; 
} 

验证厂

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; 
    }]); 
+2

你可以显示你的尝试不工作吗?另外,使用localStorage,而不是$ window.localStorage。此外,localStorage只存储字符串,所以你会希望使用JSON.stringify()和JSON.parse()来存储/检索你的对象在localStorage – holtc

+0

@holtc是的,给我几分钟!谢谢! – 2b2a

+0

@holtc它已经结束了!你能否提供一个解释,为什么不使用$ window.localStorage?我的例子使用它,因为这是我以前使用过的。 – 2b2a

回答

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

+0

关于真值问题的好处。 +1 – MBielski

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); 
}()); 

这样做,你可以简单地在你的ng-show检查visitor.loggedIn和拥有一切集中。如:

<a ng-click='visitor.logout' ng-show='visitor.loggedIn'>Log Out</a> 

更重要的是,把那些只有通过认证的用户可见的div标签的元素和隐藏/显示他们EN-质量。