使用AngularJS對(duì)路由進(jìn)行安全性處理的方法
簡(jiǎn)介
自從出現(xiàn)以后,AngularJS已經(jīng)被使用很長(zhǎng)時(shí)間了。 它是一個(gè)用于開(kāi)發(fā)單頁(yè)應(yīng)用(SPA)的javascript框架。 它有一些很好的特性,如雙向綁定、指令等。 這篇文章主要介紹Angular路由安全性策略。 它是一個(gè)可用Angular開(kāi)發(fā)實(shí)現(xiàn)的客戶端安全性框架。 我已經(jīng)對(duì)它進(jìn)行了測(cè)試。 除了保證客戶端路由安全性外,你也需要保證服務(wù)器端訪問(wèn)的安全性。 客戶端安全性策略有助于減少對(duì)服務(wù)器進(jìn)行額外的訪問(wèn)。 然而,如果一些人采用欺騙瀏覽器的手段訪問(wèn)服務(wù)器,那么服務(wù)器端安全性策略應(yīng)當(dāng)能夠拒絕未授權(quán)的訪問(wèn)。 在這篇文章中,我僅對(duì)客戶端安全性策略進(jìn)行討論。
1 在應(yīng)用模塊層面定義全局變量
為應(yīng)用定義角色:
var roles = {
superUser: 0,
admin: 1,
user: 2
};
為應(yīng)用定義未授權(quán)訪問(wèn)的路由:
var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';
2 定義授權(quán)服務(wù)
appModule.factory('authorizationService', function ($resource, $q, $rootScope, $location) {
return {
// 將權(quán)限緩存到 Session,以避免后續(xù)請(qǐng)求不停的訪問(wèn)服務(wù)器
permissionModel: { permission: {}, isPermissionLoaded: false },
permissionCheck: function (roleCollection) {
// 返回一個(gè)承諾(promise).
var deferred = $q.defer();
// 這里只是在承諾的作用域中保存一個(gè)指向上層作用域的指針。
var parentPointer = this;
// 檢查是否已從服務(wù)獲取到權(quán)限對(duì)象(已登錄用戶的角色列表)
if (this.permissionModel.isPermissionLoaded) {
// 檢查當(dāng)前用戶是否有權(quán)限訪問(wèn)當(dāng)前路由
this.getPermission(this.permissionModel, roleCollection, deferred);
} else {
// 如果還沒(méi)權(quán)限對(duì)象,我們會(huì)去服務(wù)端獲取。
// 'api/permissionService' 是本例子中的 web 服務(wù)地址。
$resource('/api/permissionService').get().$promise.then(function (response) {
// 當(dāng)服務(wù)器返回之后,我們開(kāi)始填充權(quán)限對(duì)象
parentPointer.permissionModel.permission = response;
// 將權(quán)限對(duì)象處理完成的標(biāo)記設(shè)為 true 并保存在 Session,
// Session 中的用戶,在后續(xù)的路由請(qǐng)求中可以重用該權(quán)限對(duì)象
parentPointer.permissionModel.isPermissionLoaded = true;
// 檢查當(dāng)前用戶是否有必須角色訪問(wèn)該路由
parentPointer.getPermission(parentPointer.permissionModel, roleCollection, deferred);
}
);
}
return deferred.promise;
},
//方法:檢查當(dāng)前用戶是否有必須角色訪問(wèn)該路由
//'permissionModel' 保存了從服務(wù)端返回的當(dāng)前用戶的角色信息
//'roleCollection' 保存了可訪問(wèn)當(dāng)前路由的角色列表
//'deferred' 是用來(lái)處理承諾的對(duì)象
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) {
// 如果用戶沒(méi)有必須的權(quán)限,我們把用戶引導(dǎo)到無(wú)權(quán)訪問(wèn)頁(yè)面
$location.path(routeForUnauthorizedAccess);
// 由于這個(gè)處理會(huì)有延時(shí),而這期間頁(yè)面位置可能發(fā)生改變,
// 我們會(huì)一直監(jiān)視 $locationChangeSuccess 事件
// 并且當(dāng)該事件發(fā)生的時(shí),就把掉承諾解決掉。
$rootScope.$on('$locationChangeSuccess', function (next, current) {
deferred.resolve();
});
} else {
deferred.resolve();
}
}
};
});
3 加密路由
然后讓我們用我們的努力成果來(lái)加密路由:
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)文章
關(guān)于AngularJS中ng-repeat不更新視圖的解決方法
今天小編就為大家分享一篇關(guān)于AngularJS中ng-repeat不更新視圖的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
Angular 的 Change Detection機(jī)制實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Angular 的 Change Detection機(jī)制實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
使用Angular.js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車功能
在各大購(gòu)物網(wǎng)站大家都可以簡(jiǎn)單購(gòu)物車效果演示,下面通過(guò)本文給大家分享一段代碼關(guān)于使用Angular.js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車功能,需要的朋友可以參考下2016-11-11
angularjs循環(huán)對(duì)象屬性實(shí)現(xiàn)動(dòng)態(tài)列的思路詳解
這篇文章主要介紹了angularjs循環(huán)對(duì)象屬性實(shí)現(xiàn)動(dòng)態(tài)列的思路詳解,本文給大家分享一個(gè)demo代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11
AngularJS實(shí)現(xiàn)select的ng-options功能示例
這篇文章主要介紹了AngularJS實(shí)現(xiàn)select的ng-options功能,結(jié)合實(shí)例形式分析了AngularJS使用ng-options操作select列表的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-07-07
Angular4學(xué)習(xí)筆記router的簡(jiǎn)單使用
本篇文章主要介紹了Angular4學(xué)習(xí)筆記router的簡(jiǎn)單使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
詳解JavaScript的AngularJS框架中的作用域與數(shù)據(jù)綁定
這篇文章主要介紹了JavaScript的AngularJS框架中的作用域與數(shù)據(jù)綁定,包括作用域的繼承以及數(shù)據(jù)的單向和雙向綁定等重要知識(shí)點(diǎn),需要的朋友可以參考下2016-03-03
AngularJS控制器controller給模型數(shù)據(jù)賦初始值的方法
這篇文章主要介紹了AngularJS控制器controller給模型數(shù)據(jù)賦初始值的方法,涉及AngularJS控制器controller簡(jiǎn)單賦值操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-01-01
Angularjs 動(dòng)態(tài)改變title標(biāo)題(兼容ios)
這篇文章主要介紹了 Angularjs 動(dòng)態(tài)改變title標(biāo)題(兼容ios)的相關(guān)資料,需要的朋友可以參考下2016-12-12

