在所有Angular控制器中存储用户信息

时间:2015-01-15 11:35:58

标签: angularjs authentication global

我创建了一个身份验证控制器,使用localstorage存储经过身份验证的用户信息(我使用的是Gias Kay Lee的ngStorage)。在不同的控制器中访问此信息的最佳位置(以Angular方式)是什么。我尝试使用服务代码:

myApp.factory("UserService", ["$localStorage", function ($localStorage) {
    var model = {
        IsAuthenticated: $localStorage.IsAuthenticated,
        Username: $localStorage.UserName
    };
    return model;
}]);

但是(如文档所述)表现为单身人士。

我也看过使用$ rootScope,但据我所知,这只能在myApp.run中初始化。我是对的吗?

当然我可以在每个控制器中注入ngStorage,但我很好奇如何通过创建自定义全局函数(如上面的服务)来解耦对第三方模块的依赖。

与上述相关的是获取$ scope的用户信息:

$scope.localStorageToScope = function () {
    $scope.UserName = $localStorage.UserName;
    $scope.UserEmail = $localStorage.UserEmail;
    $scope.UserRole = $localStorage.UserRole;
    $scope.IsAuthenticated = $localStorage.IsAuthenticated;
} 

我只能想到将这些代码重复到我当然不想要的每个控制器上。什么是更好的方式?

关于安全性的附注:所有安全用户操作都在服务器上重新进行身份验证,因此当有人破解本地存储机制时不会造成任何伤害。

3 个答案:

答案 0 :(得分:3)

因此,实际上您希望封装第三方服务以减少对第三方库的依赖。您的第三方库提供了一个服务$ localStorage,其中包含您要访问的某些属性。这是一种方法:

function YourAuthService($localStorage) {
  this.isAuthenticated = function () {
    return $localStorage.IsAuthenticated;
  }

  this.username = function() {
    return $localStorage.username;
  }
}
myApp.service('YourAuthService', YourAuthService);

这将创建一个可注射的包装器服务,您可以像这样使用:

function YourController(YourAuthService) {
  console.log("Current username=" + YourAuthService.username());
  console.log("Current isAuthenticated=" + YourAuthService.isAuthenticated());
}

请注意,您不需要知道您的身份验证服务如何计算您查询的数据。您只需调用适当的方法,您的身份验证服务将完成剩下的工作。这可以很容易地适应其他存储类型。

如果你想用更少的代码创建这样一个简单的包装器(在你的特殊情况下),可以这样做:

function YourAuthService($localStorage) {
  ["isAuthenticated", "username", "furtherProperty", "yadayada"].forEach(function(propertyName) {
    this[propertyName] = function() {
      return $localStorage[propertyName];
    }
  });
}
myApp.service('YourAuthService', YourAuthService);

答案 1 :(得分:1)

基本上有两种方法可以通过应用程序使用身份验证数据。您已经指定的第一种方式,即使用服务,这是一个好主意。

应避免使用

$rootScope,因为这可能会导致意外行为,因为任何模块都可以在任何地方访问它。因此,第二步可以通过为单个页面应用创建公共控制器(如$rootScope)来模仿此BaseController概念,并将其注入body标记。

<body ng-controller="BaseController">
    <!-- different pages or views -->
    <div ng-controller="HomePageController" id="home-page"></div>
</body>

现在,您可以存储应用范围内的常见数据,例如身份验证数据或BaseController范围内的任何其他内容,这些数据将直接用于其他所有控制器范围,因为现在它将成为所有控制器的父控制器范围。

第二种方法可能更有用,因为您不必像第一步那样在每个控制器中注入服务,而只需使用$scope变量来访问公共控制器中可用的任何数据,因为始终使用父范围创建控制器的范围。

希望这有帮助!

答案 2 :(得分:0)

我相信这是你正在寻找的。使用UserService中的方法重新加载模型数据。本教程应该解释一下。

//In app-modules
app.run(['authService', function (authService) {
     authService.fillAuthData();
}]);

//In authService
var _fillAuthData = function () {

    var authData = localStorageService.get('authorizationData');
    if (authData)
    {
        _authentication.isAuth = true;
        _authentication.userName = authData.userName;
    }  
 }

http://www.codeproject.com/Articles/784106/AngularJS-Token-Authentication-using-ASP-NET-Web-A