ฉันได้สร้าง github repo สรุปบทความนี้โดยพื้นฐาน: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
ng-login Github repo
Plunker
ฉันจะพยายามอธิบายให้ดีที่สุดหวังว่าฉันจะช่วยพวกคุณได้บ้าง:
(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 Service:ฟังก์ชั่นต่อไปนี้ทั้งหมดถูกนำไปใช้ในบริการ 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) เพิ่มข้อมูลของบทบาทที่อนุญาตให้เข้าถึงแต่ละเส้นทางบนบริการ $ stateProvider ของเราเตอร์ ui ดังที่เห็นด้านล่าง (สามารถใช้ได้กับ 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 interceptor:ใช้งานได้ แต่ไม่สามารถตรวจสอบขอบเขตของรหัสนี้ได้ หลังจากคำขอ $ 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);
}
};
} ]);
ป.ล.ข้อบกพร่องของการป้อนข้อมูลแบบฟอร์มอัตโนมัติตามที่ระบุไว้ในบทความที่ 1 สามารถหลีกเลี่ยงได้อย่างง่ายดายโดยการเพิ่มคำสั่งที่รวมอยู่ใน directives.js
PS2รหัสนี้สามารถปรับแต่งได้อย่างง่ายดายโดยผู้ใช้เพื่อให้สามารถมองเห็นเส้นทางต่างๆหรือแสดงเนื้อหาที่ไม่ได้ตั้งใจให้แสดง ต้องใช้ตรรกะทางฝั่งเซิร์ฟเวอร์นี่เป็นเพียงวิธีแสดงสิ่งต่าง ๆ อย่างถูกต้องบน ng-app ของคุณ