使用AngularJS對路由進(jìn)行安全性處理的方法
簡介
自從出現(xiàn)以后,AngularJS已經(jīng)被使用很長時(shí)間了。 它是一個(gè)用于開發(fā)單頁應(yīng)用(SPA)的javascript框架。 它有一些很好的特性,如雙向綁定、指令等。 這篇文章主要介紹Angular路由安全性策略。 它是一個(gè)可用Angular開發(fā)實(shí)現(xiàn)的客戶端安全性框架。 我已經(jīng)對它進(jìn)行了測試。 除了保證客戶端路由安全性外,你也需要保證服務(wù)器端訪問的安全性。 客戶端安全性策略有助于減少對服務(wù)器進(jìn)行額外的訪問。 然而,如果一些人采用欺騙瀏覽器的手段訪問服務(wù)器,那么服務(wù)器端安全性策略應(yīng)當(dāng)能夠拒絕未授權(quán)的訪問。 在這篇文章中,我僅對客戶端安全性策略進(jìn)行討論。
1 在應(yīng)用模塊層面定義全局變量
為應(yīng)用定義角色:
var roles = { superUser: 0, admin: 1, user: 2 };
為應(yīng)用定義未授權(quán)訪問的路由:
var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';
2 定義授權(quán)服務(wù)
appModule.factory('authorizationService', function ($resource, $q, $rootScope, $location) { return { // 將權(quán)限緩存到 Session,以避免后續(xù)請求不停的訪問服務(wù)器 permissionModel: { permission: {}, isPermissionLoaded: false }, permissionCheck: function (roleCollection) { // 返回一個(gè)承諾(promise). var deferred = $q.defer(); // 這里只是在承諾的作用域中保存一個(gè)指向上層作用域的指針。 var parentPointer = this; // 檢查是否已從服務(wù)獲取到權(quán)限對象(已登錄用戶的角色列表) if (this.permissionModel.isPermissionLoaded) { // 檢查當(dāng)前用戶是否有權(quán)限訪問當(dāng)前路由 this.getPermission(this.permissionModel, roleCollection, deferred); } else { // 如果還沒權(quán)限對象,我們會(huì)去服務(wù)端獲取。 // 'api/permissionService' 是本例子中的 web 服務(wù)地址。 $resource('/api/permissionService').get().$promise.then(function (response) { // 當(dāng)服務(wù)器返回之后,我們開始填充權(quán)限對象 parentPointer.permissionModel.permission = response; // 將權(quán)限對象處理完成的標(biāo)記設(shè)為 true 并保存在 Session, // Session 中的用戶,在后續(xù)的路由請求中可以重用該權(quán)限對象 parentPointer.permissionModel.isPermissionLoaded = true; // 檢查當(dāng)前用戶是否有必須角色訪問該路由 parentPointer.getPermission(parentPointer.permissionModel, roleCollection, deferred); } ); } return deferred.promise; }, //方法:檢查當(dāng)前用戶是否有必須角色訪問該路由 //'permissionModel' 保存了從服務(wù)端返回的當(dāng)前用戶的角色信息 //'roleCollection' 保存了可訪問當(dāng)前路由的角色列表 //'deferred' 是用來處理承諾的對象 getPermission: function (permissionModel, roleCollection, deferred) { var ifPermissionPassed = false; angular.forEach(roleCollection, function (role) { switch (role) { case roles.superUser: if (permissionModel.permission.isSuperUser) { ifPermissionPassed = true; } break; case roles.admin: if (permissionModel.permission.isAdministrator) { ifPermissionPassed = true; } break; case roles.user: if (permissionModel.permission.isUser) { ifPermissionPassed = true; } break; default: ifPermissionPassed = false; } }); if (!ifPermissionPassed) { // 如果用戶沒有必須的權(quán)限,我們把用戶引導(dǎo)到無權(quán)訪問頁面 $location.path(routeForUnauthorizedAccess); // 由于這個(gè)處理會(huì)有延時(shí),而這期間頁面位置可能發(fā)生改變, // 我們會(huì)一直監(jiān)視 $locationChangeSuccess 事件 // 并且當(dāng)該事件發(fā)生的時(shí),就把掉承諾解決掉。 $rootScope.$on('$locationChangeSuccess', function (next, current) { deferred.resolve(); }); } else { deferred.resolve(); } } }; });
3 加密路由
然后讓我們用我們的努力成果來加密路由:
var appModule = angular.module("appModule", ['ngRoute', 'ngResource']) .config(function ($routeProvider, $locationProvider) { $routeProvider .when('/superUserSpecificRoute', { templateUrl: '/templates/superUser.html', // 路由的 view/template 路徑 caseInsensitiveMatch: true, controller: 'superUserController', // 路由的 angular 控制器 resolve: { // 在這我們將使用我們上面的努力成果,調(diào)用授權(quán)服務(wù) // resolve 是 angular 中一個(gè)非常贊的特性,可以確保 // 只有當(dāng)它下面提到的承諾被處理之后 // 才將控制器(在本例中是 superUserController)應(yīng)用到路由。 permission: function (authorizationService, $route) { return authorizationService.permissionCheck([roles.superUser]); }, } }) .when('/userSpecificRoute', { templateUrl: '/templates/user.html', caseInsensitiveMatch: true, controller: 'userController', resolve: { permission: function (authorizationService, $route) { return authorizationService.permissionCheck([roles.user]); }, } }) .when('/adminSpecificRoute', { templateUrl: '/templates/admin.html', caseInsensitiveMatch: true, controller: 'adminController', resolve: { permission: function (authorizationService, $route) { return authorizationService.permissionCheck([roles.admin]); }, } }) .when('/adminSuperUserSpecificRoute', { templateUrl: '/templates/adminSuperUser.html', caseInsensitiveMatch: true, controller: 'adminSuperUserController', resolve: { permission: function (authorizationService, $route) { return authorizationService.permissionCheck([roles.admin, roles.superUser]); }, } }); });
相關(guān)文章
AngularJS實(shí)現(xiàn)元素顯示和隱藏的幾個(gè)案例
這篇文章主要介紹了AngularJS實(shí)現(xiàn)元素顯示和隱藏的幾個(gè)案例,需要的朋友可以參考下2015-12-12AngularJs bootstrap搭載前臺(tái)框架——準(zhǔn)備工作
本文主要介紹AngularJs bootstrap搭載前臺(tái)框架,這里對Bootstrap 搭載環(huán)境,及注意事項(xiàng)做了講解,有需要的小伙伴可以參考下2016-09-09將angular.js項(xiàng)目整合到.net mvc中的方法詳解
這篇文章主要給大家介紹了將angular.js項(xiàng)目整合到.net mvc中的相關(guān)資料,文中通過示例代碼將實(shí)現(xiàn)的過程介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起看看吧。2017-06-06AngularJS基礎(chǔ) ng-dblclick 指令用法
本文主要介紹AngularJS ng-dblclick 指令,這里對ng-dblclick基礎(chǔ)資料整理并詳細(xì)介紹,簡單的代碼實(shí)例和實(shí)現(xiàn)效果,希望能幫助學(xué)習(xí)AngularJS的朋友2016-08-08