Angularjs 跨所有角度控制器存储用户信息

Angularjs 跨所有角度控制器存储用户信息,angularjs,authentication,global,Angularjs,Authentication,Global,我创建了一个身份验证控制器,它使用localstorage存储经过身份验证的用户信息(我使用的是Gias Kay Lee提供的ngStorage)。在不同控制器中访问此信息的最佳位置(以角度方式)是什么。我尝试使用服务,代码: myApp.factory("UserService", ["$localStorage", function ($localStorage) { var model = { IsAuthenticated: $localStorage.IsAut

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

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;
} 
我只能想到对每个控制器重复这段代码,当然我不想这样。有什么更好的办法


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

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

$rootScope
应该避免,因为这可能会导致意外行为,因为任何模块都可以在任何地方访问它。因此,第二步可以是模仿这个
$rootScope
概念,为一个单页应用程序创建一个像
BaseController
这样的通用控制器,并将其注入到你的
body
标签中

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

现在,您可以在
BaseController
范围内存储应用程序范围内的通用数据,如身份验证数据或任何其他数据,这些数据将直接用于所有其他控制器范围,因为这将是所有控制器的父控制器范围

第二种方法可能更有用,因为您不必像第一步那样在每个控制器中注入服务,相反,您可以使用
$scope
变量访问公共控制器中可用的任何数据,因为控制器的作用域总是使用父作用域创建的


希望这有帮助

因此,实际上您希望封装第三方服务,以减少对第三方库的依赖。您的第三方库提供了一个服务$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);
请注意,您不需要知道auth服务是如何计算您查询的数据的。您只需调用适当的方法,您的身份验证服务将完成其余工作。这可以很容易地适应其他存储类型

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

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

我相信这就是你要找的。使用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;
    }  
 }

帮了大忙!非常感谢,刚刚成功测试了您的第一种方法。第二个不起作用,因为ngStorage似乎不支持类似阵列的存储机制。但是我喜欢这个建议。真的很有趣。谢谢你分享这个想法。虽然我还没有实现一个类似SPA的站点(我仍在使用单独的HTML页面,因为有些页面包含重磅JQuery控件/图像,如主页,我不想破坏我的核心角度页面。但我的下一步行动将完全删除JQuery控件,以支持一个完整的角度站点。然后你的想法将变得非常方便。