使用AngularJS对路由进行安全性处理的方法
程序员文章站
2022-03-14 16:27:20
简介
自从出现以后,angularjs已经被使用很长时间了。 它是一个用于开发单页应用(spa)的javascript框架。 它有一些很好的特性,如双向绑定、...
简介
自从出现以后,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(); } } }; });
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]); }, } }); });
上一篇: 详解AngularJS的通信机制
下一篇: 说,快说,你的私房钱哪里来的