AngularJS:将数据从控制器传递到应用程序配置



我对Angular很陌生。我在我的Angular应用程序中使用令牌身份验证。我使用HTTP拦截器来检查我的后端何时返回401,然后使用刷新令牌进行登录:

myapp.config(...)
...
$httpProvider.interceptors.push(['$q', '$injector', function($q, $injector) {
  var sessionRecoverer = {
    responseError: function(response) {
      // Session has expired
      if (response.status === 401) {
        var $http = $injector.get('$http');
        var deferred = $q.defer();
        var $auth = $injector.get('$auth');
        $auth.login({
          refresh_token: ????,
          grant_type: 'refresh_token',
          event_client: 'client',
          client_id: 'id'
        });
        // When the session recovered, make the same backend call again and chain the request
        return deferred.promise.then(function() {
          return $http(response.config);
        });
      }
      return $q.reject(response);
    }
  };
  return sessionRecoverer;
}]);

现在,refresh_token来自我的登录控制器(它从api后端提取它)。因此,控制器必须以某种方式将其传递给拦截器。问题是拦截器在配置块中,所以没有服务、值等,只有提供者。但是提供者不能被注入控制器。那么,有没有一种方法可以将数据从控制器传递到app.config?如果没有,是否有解决方法?注入器是否可以位于app.config之外的其他位置?

是的,你可以简单地这样做:

    myapp.config(...)
    ...
    $httpProvider.interceptors.push(['$q', '$injector', function($q, $injector, TokenFactory) {
      var sessionRecoverer = {
        responseError: function(response) {
          // Session has expired
          if (response.status === 401) {
            var $http = $injector.get('$http');
            var deferred = $q.defer();
            var $auth = $injector.get('$auth');
            $auth.login({
              refresh_token: TokenFactory.getRefreshToken(),
              grant_type: 'refresh_token',
              event_client: 'client',
              client_id: 'id'
            });
            // When the session recovered, make the same backend call again and chain the request
            return deferred.promise.then(function() {
              return $http(response.config);
            });
          }
          return $q.reject(response);
        }
      };
      return sessionRecoverer;
    }]);

正如您所说,块配置只能注入提供程序,但拦截器本身是一个工厂,因此您可以注入其他工厂,例如,一个名为TokenFactory的工厂,它应该提供一个在需要时返回刷新令牌的方法。

编辑

如果refresh_token是来自后端的东西,并且你想从登录控制器在TokenFactory中设置一个值,你可以这样做来实现你的工厂和控制器:

myapp.factory('TokenFactory',function(){
  var currentRefreshToken;
  return {
    setRefreshToken: function(token){
      currentRefreshToken = token;
    },
    getRefreshToken: function(){
      return currentRefreshToken:
    }
  };
});
myapp.controller('MyLoginCtrl',function($scope,TokenFactory,$http){
  $scope.login = function(){
    $http.post('http://myapp.com/refreshtoken',$scope.credentials)
      .then(TokenFactory.setRefreshToken)
      .then(function(){ /* ... */})
      .catch(function(err){ console.error(err) })
    ;
  };
});

数据持久性

如果你想让你的令牌持久化,你可以写一个使用LocalStorage HTML5 API的工厂,并在你的TokenFactory:中使用它

myapp.factory('TokenFactory',function(LocalStorage){
  // load the value from localstorage (hard disk) on app starts
  var currentRefreshToken = LocalStorage.get('myapp.currentRefreshToken');
  return {
    setRefreshToken: function(token){
      currentRefreshToken = token; // save value in RAM
      LocalStorage.set('myapp.currentRefreshToken',token); // and sync the localstorage value
    },
    getRefreshToken: function(){
      return currentRefreshToken; // quick access to the value from RAM
    }
  };
});
myapp.factory('LocalStorage',function($window) {
    var localStorage = {};
    localStorage.set = function(key, value) {
        $window.localStorage[key] = value;
    };
    localStorage.get = function(key, defaultValue) {
        return $window.localStorage[key] || defaultValue;
    };
    localStorage.setObject = function(key, value) {
        $window.localStorage[key] = JSON.stringify(value);
    };
    localStorage.getObject = function(key) {
        return (!$window.localStorage[key] || $window.localStorage[key] === undefined) ? {} : JSON.parse($window.localStorage[key]);
    };
    localStorage.setArray = function(key, array){
        if (!array.length) {
            console.debug(array);
            $window.localStorage[key] = '[]';
        } else{
            this.setObject(key, array);                    
        }
    };
    localStorage.getArray = function(key){
        return (!$window.localStorage[key] || $window.localStorage[key] === undefined) ? [] : JSON.parse($window.localStorage[key]);
    };
    localStorage.exportAsFile = function(key, fileName){        
        var data = [$window.localStorage[key]] || ['{}'];
        var blob = new Blob(data,{type:'application/json;charset=utf-8'});
        $window.saveAs(blob,fileName);
    };
    return localStorage;
});

相关内容

  • 没有找到相关文章