我创建了一个身份验证控制器,使用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;
}
我只能想到将这些代码重复到我当然不想要的每个控制器上。什么是更好的方式?
关于安全性的附注:所有安全用户操作都在服务器上重新进行身份验证,因此当有人破解本地存储机制时不会造成任何伤害。
答案 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