基本的にこの記事をまとめたgithubリポジトリを作成しました:https : //medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
ng-login Githubリポジトリ
プランカー
私は可能な限り説明するように努めますが、私はあなた方の何人かを助けることを願っています:
(1)app.js:アプリ定義での認証定数の作成
var loginApp = angular.module('loginApp', ['ui.router', 'ui.bootstrap'])
/*Constants regarding user login defined here*/
.constant('USER_ROLES', {
all : '*',
admin : 'admin',
editor : 'editor',
guest : 'guest'
}).constant('AUTH_EVENTS', {
loginSuccess : 'auth-login-success',
loginFailed : 'auth-login-failed',
logoutSuccess : 'auth-logout-success',
sessionTimeout : 'auth-session-timeout',
notAuthenticated : 'auth-not-authenticated',
notAuthorized : 'auth-not-authorized'
})
(2)認証サービス:以下のすべての機能はauth.jsサービスに実装されています。$ httpサービスは、認証手順のためにサーバーと通信するために使用されます。承認に関する機能も含まれています。つまり、ユーザーが特定のアクションの実行を許可されている場合です。
angular.module('loginApp')
.factory('Auth', [ '$http', '$rootScope', '$window', 'Session', 'AUTH_EVENTS',
function($http, $rootScope, $window, Session, AUTH_EVENTS) {
authService.login() = [...]
authService.isAuthenticated() = [...]
authService.isAuthorized() = [...]
authService.logout() = [...]
return authService;
} ]);
(3)セッション:ユーザーデータを保持するシングルトン。ここでの実装はあなた次第です。
angular.module('loginApp').service('Session', function($rootScope, USER_ROLES) {
this.create = function(user) {
this.user = user;
this.userRole = user.userRole;
};
this.destroy = function() {
this.user = null;
this.userRole = null;
};
return this;
});
(4)親コントローラー:これをアプリケーションの「メイン」機能と見なしてください。すべてのコントローラーがこのコントローラーから継承され、これがこのアプリの認証のバックボーンです。
<body ng-controller="ParentController">
[...]
</body>
(5)アクセス制御:特定のルートでアクセスを拒否するには、2つのステップを実装する必要があります。
a)以下に示すように、UIルーターの$ stateProviderサービスで、各ルートへのアクセスを許可されたロールのデータを追加します(ngRouteでも同じことができます)。
.config(function ($stateProvider, USER_ROLES) {
$stateProvider.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard/index.html',
data: {
authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor]
}
});
})
b)$ rootScope。$ on( '$ stateChangeStart')に、ユーザーが承認されていない場合に状態が変化しないようにする関数を追加します。
$rootScope.$on('$stateChangeStart', function (event, next) {
var authorizedRoles = next.data.authorizedRoles;
if (!Auth.isAuthorized(authorizedRoles)) {
event.preventDefault();
if (Auth.isAuthenticated()) {
// user is not allowed
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
} else {
// user is not logged in
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
}
});
(6)Authインターセプター:これは実装されていますが、このコードのスコープでは確認できません。各$ httpリクエストの後、このインターセプターはステータスコードをチェックし、以下のいずれかが返された場合、イベントをブロードキャストしてユーザーに再度ログインを強制します。
angular.module('loginApp')
.factory('AuthInterceptor', [ '$rootScope', '$q', 'Session', 'AUTH_EVENTS',
function($rootScope, $q, Session, AUTH_EVENTS) {
return {
responseError : function(response) {
$rootScope.$broadcast({
401 : AUTH_EVENTS.notAuthenticated,
403 : AUTH_EVENTS.notAuthorized,
419 : AUTH_EVENTS.sessionTimeout,
440 : AUTH_EVENTS.sessionTimeout
}[response.status], response);
return $q.reject(response);
}
};
} ]);
PS第1回の記事で述べたフォームデータの自動入力に関するバグは、directives.jsに含まれているディレクティブを追加することで簡単に回避できます。
PS2このコードは、ユーザーが簡単に調整して、さまざまなルートを表示したり、表示することを意図していないコンテンツを表示したりすることができます。ロジックはサーバー側に実装する必要があります。これは、ng-appで正しく表示するための方法です。