1

每次路由更改时,我都会检查是否使用当前登录的用户详细信息设置了一个变量,如果未设置此变量,我只需重定向到登录页面。

现在我正在尝试实现某种“记住我”功能,所以每次路由更改时,如果变量用户不存在而不是重定向到登录页面,我会检查本地存储是否有“authtoken”,如果设置了,我调用一个检查函数,将 authtoken 传递给服务器,它返回用户,应用程序将与手动登录后的工作方式相同(返回与检查函数相同的用户)。

我很确定这不是最好的方法。

如果我重新加载页面,首先我运行检查函数,将 authtoken 发送到服务器并等待响应,如果用户存在,则将该值分配给 rootscope 中的变量。

例如,我有不同的服务使用 rootscope 中的变量

angular.module('myApp')
    .service('AdminService', function AdminService($rootScope, $http, StorageService) {
    var authtoken = StorageService.get('authtoken');
    var clientId = $rootScope.loggedUser.id;

当然,当检查功能运行时,它会等待响应,但服务正在被实例化并且 $rootScope.loggedUser.id 不存在。

如何告诉应用程序等到检查功能收到响应?

这是我的代码

....
}).run(function($rootScope, $location, AuthService, StorageService) {

var intended = $location.path();  

AuthService.check().success(function(data) {
    if(data.user) {
       $rootScope.loggedUser = data.user;
       $location.path(intended);
    } else $location.path('login');
});
$rootScope.$on('$routeChangeStart', function() {

  if($rootScope.loggedUser) {
  ....

例如,如果用户将页面“myapp.com/#/admin/users”添加为书签,我不想重定向到登录,如果我在本地存储中有 authtoken,但这会导致控制器被实例化,即使用该服务,该服务需要尚未填充的 $rootScope.loggedUser.id。

而且我只想在页面(重新)加载时(不是每次用户更改路线时)运行功能检查。

4

1 回答 1

1

如果您需要服务调用来检查您的身份验证令牌,我建议您重新检查您的设计。身份验证令牌通常存储有过期时间,因此您只需检查您是否在过期期限内而无需调用服务器。您不会损害安全性,因为身份验证令牌由服务器签名,并在您进行服务器调用以执行任何有用的操作时进行验证。因此,在正常情况下,不需要单独check调用。

但是,如果你坚持,这个用例最好用resolve路由的属性来处理。然而,这意味着每个关心用户登录状态的路由都必须定义一个解析属性。这并不意味着您必须在每次路由更改时调用该服务。

与其$rootScope.loggedUser用来存储用户,不如让它由 缓存并通过参数AuthService注入。resolve

因此,您可以执行以下操作:

$routeProvider
   .when("some/secure/route", {
          controller: "SecureCtrl",
          resolve: {
             user: AuthService.checkUser
          }
        });

在您的 AuthService 中:

...
checkUser: function(){
  var deferred = $q.defer();

  if (cachedUser){
     deferred.resolve(cachedUser);
  } else {

     AuthService.check().success(
        function(data){
           // cachedUseris defined at AuthService's scope
           cachedUser = data.user;
           deferred.resolve(data.user);
        });
  }

  return deferred.promise;
}

然后,在您的控制器中:

.controller("SecureCtrl", function(user){
   $scope.userId = user.id;
}
于 2014-11-03T04:38:23.973 回答