2016-06-22 12 views
1

AngularJSアプリケーションでルートのパーミッションをチェックしようとしています。経路は角度uiルータによって処理されます。

マイルートや権限あたりのルートは、このように定義されています

angular.module('my_app') 
    .config(function ($stateProvider, $urlRouterProvider) { 
    $stateProvider 
     .state('root', { 
      abstract: true, 
      templateUrl: 'content.html', 
      resolve: { 
       user_info: function (UserService) { 
        return UserService.user_info(); 
       } 
      } 
     }) 
     .state('root.some_page', { 
      url: '/', 
      templateUrl: 'some_page.html', 
      controller: 'home', 
      data: { 
       roles: ['some_right', 'some_other_right] 
      } 
     }); 
} 

私は、このようなアクセス許可を確認してください:

[...].run(function ($rootScope, $state, UserService) { 
    $rootScope.$on('$stateChangeStart', 
     function (event, toState) { 
      if (!!toState.data) { 
       var required_roles = toState.data.roles; 
       if (!UserService.has_permission_in(required_roles)) { 
        event.preventDefault(); 
        $state.go('root.access_forbidden'); 
       } 
      } 
     }); 
}); 

すべて今のところ良いです。私の問題は、ユーザーのアクセス許可を解決することです。バックエンドによって提供され、$http.get(...)を使用して取得されます。 サービスは約束を返すので、$stateChangeStartがイベントトリガーされたときに必ずしも結果が得られるわけではありません。

アプリケーションが「暖かい」ときは「良い」が、保護されたページに着くと失敗します(データは準備ができていません)。私は約束を待つ方法がありません。

ルート上でアクセス制御を行う「良い」方法は何でしょうか?あなたの保護された状態の定義では

答えて

1

:新しい状態に移行する前に解決する約束を待ち

.state('root.some_page', { 
      url: '/', 
      templateUrl: 'some_page.html', 
      controller: 'home', 
      resolve: { 
      access: function($http, $state){ //Note: you can inject your own services/factories too 
      var requiredPermissions = ['some_right', 'some_other_right']; 
       return $http.get(...).then(function(response){ 
       var permissions = response.data.permissions; 
       var granted = permissions.reduce((prev,curr) => requiredPermissions.indexOf(curr) > -1 || prev, false); 
       if(!granted) 
       $state.go('publicState'); 
       return permissions; 
       }); 
      } 
      } 
     }) 

解決。

ベター:

素敵な音
function checkPermissions(requiredPermissions){ 
return function ($http, $state){ //Note: you can inject your own services/factories too 
       return $http.get(...).then(function(response){ 
       var permissions = response.data.permissions; 
       var granted = permissions.reduce((prev,curr) => requiredPermissions.indexOf(curr) > -1 || prev, false); 
       if(!granted) 
       $state.go('publicState'); 
       return permissions; 
       }); 
      } 
} 

//In state definition 
.state('root.some_page', { 
     url: '/', 
     templateUrl: 'some_page.html', 
     controller: 'home', 
     resolve: { 
     access: checkPermissions(['first','second']) 
     } 
    }) 
+0

、感謝します。しかし、私が多くの保護されたルートを持っているなら、それは私のすべての州のためにこのコードをすべて複製しなければならないということですか? –

+0

または、アクセス許可のリストを引数として受け取り、これらのアクセス許可に対して検証する関数を返す関数を作成します。私は私の答えを編集します。 –

関連する問題