Я створив github repo, підсумовуючи цю статтю в основному: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
ng-логін Github repo
Плункер
Я спробую пояснити якомога краще, сподіваюся, я допоможу деяким з вас там:
(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: Усі наступні функції реалізовані в службі 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 кроки:
а) Додайте дані про ролі, дозволені для доступу до кожного маршруту, в службі $ 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 Помилка з автоматичним заповненням даних форми, як зазначено в першій статті, можна легко уникнути, додавши директиву, що входить до direc.s.
PS2 Цей код може бути легко налаштований користувачем, щоб можна було бачити різні маршрути або відображати вміст, який не передбачався для відображення. Логіка ОБОВ'ЯЗКОВО бути реалізованою на сервері, це лише спосіб правильно показати речі у вашому ng-додатку.