自從出現以後,AngularJS已經被使用很長時間了。 它是一個用於開發單頁應用(SPA)的javascript框架。 它有一些很好的特性,如雙向綁定、指令等。 這篇文章主要介紹Angular路由安全性策略。 它是一個可用Angular開發實現的客戶端安全性框架。 我已經對它進行了測試。 除了保證客戶端路由安全性外,你也需要保證服務器端訪問的安全性。 客戶端安全性策略有助於減少對服務器進行額外的訪問。 然而,如果一些人采用欺騙浏覽器的手段訪問服務器,那麼服務器端安全性策略應當能夠拒絕未授權的訪問。 在這篇文章中,我僅對客戶端安全性策略進行討論。
為應用定義角色:
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();
}
}
};
});
然後讓我們用我們的努力成果來加密路由:
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]);
},
}
});
});
希望你喜歡,並分享我的工作~帶你走近AngularJS系列:
如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm
在 AngularJS 應用中通過 JSON 文件來設置狀態 http://www.linuxidc.com/Linux/2014-07/104083.htm
AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm
AngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交數據 http://www.linuxidc.com/Linux/2014-07/104402.htm
AngularJS 的詳細介紹:請點這裡
AngularJS 的下載地址:請點這裡