如何用 ui-router 传递 header 信息?

How to pass header info with ui-router?

我有一个 angular 应用程序,它通过基于令牌的身份验证系统与 rails 后端通信。

当我使用 ngRoute 时,我有一个拦截器,它会从 cookie 存储中获取令牌并将其添加到 headers 以针对向服务器发出的每个请求。

然后它会侦听状态并在令牌未授权时重定向到登录。

如何使用 ui-router 执行此操作?它的工作方式似乎不同。

分享我想出的解决方案:

angular.module 'saAuthentication', []

  .config ($stateProvider, $urlRouterProvider) ->
    $stateProvider
      .state 'login',
        url: '/login',
        templateUrl: 'app/authentication/sessions/login.html',

  .run ($rootScope, $state, localStorageService) ->
    $rootScope.$on "$stateChangeStart", (event, toState, toParams, fromState, fromParams) ->
      if localStorageService.cookie.get('X-User-Token') == null
        event.preventDefault()
        $state.go('login', null, { notify: false }).then (state) ->
          $rootScope.$broadcast('$stateChangeSuccess', state, null)

区别在于监听事件,当使用ui-router监听$stateChangeStart.

$rootScope.$on('$stateChangeStart',
    function (event, toState, toParams, fromState, fromParams) {
    // redirect to login here if the token doesn't exist
    })

您可以使用 $stateChangeError

轻松完成此操作

建议

How-to

  • resolve 中使用承诺接受或拒绝给定状态的身份验证,并且
  • 如果 promise 被拒绝,处理 $stateChangeError 进入不同的状态。

例子

在你的 .config() 中用 resolve 声明状态,像这样:

app.config(['$stateProvider',function($stateProvider) {
  $stateProvider.state('profile', {
    url: '/profile',
    template: '<h1>Hello authenticated user!</h1>',
    resolve: {
     authState: function($q, $timeout) {
        var deferred = $q.defer();
        //Simulate $http request with a $timeout
        $timeout(function() {
          deferred.reject("AUTH_REQUIRED");
        }, 1000);
        return deferred.promise;
      }
    }
  });
}]);

并在 .run() 中设置 $stateChangeError 观察者,如下所示:

app.run(function ($rootScope,   $state,   $stateParams) {
  $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
    event.preventDefault();
    if (error === "AUTH_REQUIRED") {
      console.log("ERROR:", error, "URL:", toState.url, "PARAMS:", toParams);
      //not authenticated, go to login instead of the route change
      $state.go('login');
    }
  });
});

说明

  • 在上面的示例中,我使用 $timeout 来模拟身份验证错误。
    • 它在一秒钟后拒绝承诺并出现错误 'AUTH_REQUIRED'
    • $stateChangeError watcher 捕捉到这个错误,并做出相应的响应。
  • 您要做的是使用 $http service 发出您的身份验证请求,然后...
    • 接受.success(),
    • 中的承诺
    • 拒绝 .error() 中的承诺。

这是直接从 $http documentation 发出请求的一般用法示例:

// Simple GET request example :
$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

.success()中,您可以相应地检查headers和accept/reject承诺。您应该拒绝[=27]中的承诺=].

希望对您有所帮助!