AngularJS 路由的安全性處理

jopen 10年前發布 | 24K 次閱讀 JavaScript開發 angularjs

簡介

自從出現以后,AngularJS已經被使用很長時間了。 它是一個用于開發單頁應用(SPA)的javascript框架。 它有一些很好的特性,如雙向綁定、指令等。 這篇文章主要介紹Angular路由安全性策略。 它是一個可用Angular開發實現的客戶端安全性框架。 我已經對它進行了測試。 除了保證客戶端路由安全性外,你也需要保證服務器端訪問的安全性。 客戶端安全性策略有助于減少對服務器進行額外的訪問。 然而,如果一些人采用欺騙瀏覽器的手段訪問服務器,那么服務器端安全性策略應當能夠拒絕未授權的訪問。 在這篇文章中,我僅對客戶端安全性策略進行討論。

1 噠噠: 在應用模塊層面定義全局變量

為應用定義角色:

var roles = {
    superUser: 0,
    admin: 1,
    user: 2
}; 

為應用定義未授權訪問的路由:

var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';

2 噠噠: 定義授權服務

appModule.factory('authorizationService', function ($resource, $q, $rootScope, $location) {
    return {
        // 將權限緩存到 Session,以避免后續請求不停的訪問服務器
        permissionModel: { permission: {}, isPermissionLoaded: false },

        permissionCheck: function (roleCollection) {             // 返回一個承諾(promise).             var deferred = $q.defer();

            // 這里只是在承諾的作用域中保存一個指向上層作用域的指針。             var parentPointer = this;

            // 檢查是否已從服務獲取到權限對象(已登錄用戶的角色列表)             if (this.permissionModel.isPermissionLoaded) {

                // 檢查當前用戶是否有權限訪問當前路由                 this.getPermission(this.permissionModel, roleCollection, deferred);             } else {                 // 如果還沒權限對象,我們會去服務端獲取。                 // 'api/permissionService' 是本例子中的 web 服務地址。

                $resource('/api/permissionService').get().$promise.then(function (response) {                     // 當服務器返回之后,我們開始填充權限對象                     parentPointer.permissionModel.permission = response;

                    // 將權限對象處理完成的標記設為 true 并保存在 Session,                     // Session 中的用戶,在后續的路由請求中可以重用該權限對象                     parentPointer.permissionModel.isPermissionLoaded = true;

                    // 檢查當前用戶是否有必須角色訪問該路由                     parentPointer.getPermission(parentPointer.permissionModel, roleCollection, deferred);                 }                 );             }             return deferred.promise;         },

        //方法:檢查當前用戶是否有必須角色訪問該路由         //'permissionModel' 保存了從服務端返回的當前用戶的角色信息         //'roleCollection' 保存了可訪問當前路由的角色列表         //'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) {                 // 如果用戶沒有必須的權限,我們把用戶引導到無權訪問頁面                 $location.path(routeForUnauthorizedAccess);                 // 由于這個處理會有延時,而這期間頁面位置可能發生改變,                  // 我們會一直監視 $locationChangeSuccess 事件                 // 并且當該事件發生的時,就把掉承諾解決掉。                 $rootScope.$on('$locationChangeSuccess', function (next, current) {                     deferred.resolve();                 });             } else {                 deferred.resolve();             }         }     }; });</pre>

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: {
                    // 在這我們將使用我們上面的努力成果,調用授權服務
                    // resolve 是 angular 中一個非常贊的特性,可以確保
                    // 只有當它下面提到的承諾被處理之后
                    // 才將控制器(在本例中是 superUserController)應用到路由。
                    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]);
                    },
                }
            });
    });

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!