推迟Angular UI路由器$ stateChangeStart,直到收到服务器授权响应

axe*_*lav 13 javascript authorization coffeescript angularjs angular-ui-router

我有一个使用UI路由器的Angular应用程序,我试图在应用程序运行时验证用户的令牌(如果存在).我还检查用户是否有权访问某些路线.问题是$stateChangeStart在我从授权端点收到响应之前正在运行.这是一些代码(coffeescript与js下面) - 这都在我的run块内.

app.run(($rootScope, $state, $stateParams, $log, Auth) ->

  currentState = 'home'

  $rootScope.$state = $state

  # read a cookie if cookie exists
  if Auth.setAuthenticationToken()
    # hit api endpoint to validate token
    Auth.validateToken (user) ->
      # route to current state
      # this returns after $stateChangeStart runs below
      $state.go(currentState)

  $rootScope.$on '$stateChangeStart', (event, toState, toParams, fromState, fromParams) ->

    currentState = toState.name

    Auth.setAuthenticationToken()

    $rootScope.error = null

    # compare users access permissions with incoming route's access level
    if (!Auth.authorize toState.data.access, Auth.user)
      event.preventDefault()
      $rootScope.error = "Sorry, you haven't provided the required credentials."
      $log.warn $rootScope.error
)
Run Code Online (Sandbox Code Playgroud)

我的问题是如何$stateChangeStart在返回auth端点的响应后才能运行.这只需要第一次发生.每次后续状态更改都可以在不命中auth端点的情况下完成.

cal*_*oyd 6

我将在您的Auth服务中创建一个返回promise 的函数.之后,解决(授权)或拒绝(未授权)延期.然后在resolve路径定义的属性上使用它

$stateProvider.state('stateName',{
    ...
    ...
    resolve: {
         isAuthorized: function(Auth){
             return Auth.checkAuthorization();
         }
    }
})
Run Code Online (Sandbox Code Playgroud)

为了支持后续检查,您可以在服务中维护承诺.这可能如下所示:

myApp.service('Auth',function($http,$q){
    var authStatusDeferred = $q.defer();
    this.checkAuthorization = function(){
        return authStatusDeferred.promise;
    };

    this.validateToken = function(user){
        var isValid = false;
        //..do validation stuff
        if(isValid) authStatusDeferred.resolve();
        //Otherwise state change will not happen..            
    };



});
Run Code Online (Sandbox Code Playgroud)

哦,抱歉没有咖啡