外部サービスによるルートの簡単な認証チェックを作成したいと思います。
ルートオブジェクトのアクセス要件を定義します。
$routeProvider
.when('/', {
templateUrl: 'src/app/views/index.html',
controller: 'indexCtrl',
authenticated: true
})
.when('/login', {
templateUrl: 'src/app/views/login.html',
controller: 'loginCtrl',
anonymous: true
})
.otherwise({
redirectTo: '/'
})
;
次に、$routeChangeStart
イベント内で権限を持っているかどうかを確認します。
$rootScope.$on('$routeChangeStart', function (event, next) {
if(next.authenticated && !$myService.isLoggedin())
$location.path("/login");
else if(next.anonymous && $myService.isLoggedin())
$location.path("/secured");
});
実際に、それは動作します-
認証されていないユーザーがログインページに移動した場合、認証されていてもルートが匿名ユーザーのみの場合、ユーザーを別のページに移動するなど。
ただし、このリダイレクトは実際にコントローラーとテンプレートがロードされた後に発生します!そして、コントローラーは、私のREST API、 m認証されていません。
処理する前にどのようにルートを処理できますか?
私の解決策は$locationChangeStart
と$routeChangeStart
を組み合わせることでした:
$rootScope.$on('$locationChangeStart', function (event) {
//If login data not available, make sure we request for it
if($facebook.isConnected()==null) {
$facebook.getLoginStatus();
event.preventDefault();
return;
}
var next=parseRoute().$$route;
if(!Auth.loginCheck(next))
event.preventDefault();
});
parseRoute()
をangular-route.js
からコピーして、指定されたURLを解析してルーティングしました。
次に、ログインチェックハンドラー(Auth.loginCheck
)を作成し、失敗するとfalseを返すようにします。
また、$routeChangeStart
を使用して$route.reload()
イベントを処理するため、認証ステータス内のすべての変更後に$route.reload()
を実行します。
$rootScope.$on('$routeChangeStart', function (event, next) {
Auth.loginCheck(next);
});
最後に、単純なrun()
メソッドを使用して、このカスタムサービスが常に実行されることを確認します。
私たちは今、その正確な問題を解決するために設計したモジュールであるngAuthを使用しています(以前にここで与えた答えに基づいて)。
最後に、この問題を解決する角度モジュールを開発しました。このモジュールは、以前にここで公開した回答に基づいています。
ここでのリクエストにより、現在動作するベータリリースを公開しました。 http://github.com/GoDisco/ngAuth
気軽に使用してください。
$ routeProvider resolve を使用します
.when('/', {
templateUrl: 'src/app/views/index.html',
controller: 'indexCtrl',
resolve: function($q, $location) {
var deferred = $q.defer();
deferred.resolve();
if (!isAuthenticated) {
$location.path('/login');
}
return deferred.promise;
}
})
ルートのresolve
プロパティを使用してみてください。コントローラまたはテンプレートがロードされる前に、渡されたすべての機能/依存関係を解決します。依存関係がプロミスを返す場合、解決されたものは何もロードされません。
解決に認証サービスを渡し、認証エラーの場合にリダイレクトしてください。
ご覧ください-> https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw
$ stateProviderは、下で$ routeProviderを使用します。このwikiはより多くの洞察を与えてくれます。 https://github.com/angular-ui/ui-router/wiki#resolve
Angularjsの解決例:
.when('/profile', {
templateUrl: 'views/profile.html',
controller: 'ProfileCtrl',
resolve: {
app: function($q, $rootScope, $location) {
var defer = $q.defer();
if ($rootScope.currentUser == undefined) {
$location.path('/login');
};
defer.resolve();
return defer.promise;
}
}
Angular-http-authを使用すると、HTTPレベル(テンプレートの取得時)で非常にエレガントな承認を処理し、必要に応じてログインを要求できます。許可が拒否された場合、テンプレート(コントローラーも)をロードすることなく、すべてのこと。明らかにこれまで見た中で最高のもの。