使用AngularJS对路由进行安全性处理的方法


Posted in Javascript onJune 18, 2015

 简介

自从出现以后,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]);
          },
        }
      });
  });
Javascript 相关文章推荐
获取当前网页document.url location.href区别总结
May 10 Javascript
javascript 兼容鼠标滚轮事件
Apr 07 Javascript
JS 控制非法字符的输入代码
Dec 04 Javascript
使用Firebug对js进行断点调试的图文方法
Apr 02 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
JS简单编号生成器实现方法(附demo源码下载)
Apr 05 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
May 12 Javascript
JQuery 的跨域方法推荐_可跨任何网站
May 18 Javascript
JavaScript实现垂直滚动条效果
Jan 18 Javascript
r.js来合并压缩css文件的示例
Apr 26 Javascript
通过javascript实现段落的收缩与展开
Jun 26 Javascript
一文秒懂JavaScript构造函数、实例、原型对象以及原型链
Aug 25 Javascript
浅谈Node.js中的定时器
Jun 18 #Javascript
浅析AngularJS中的生命周期和延迟处理
Jun 18 #Javascript
Node.js事件驱动
Jun 18 #Javascript
详解AngularJS的通信机制
Jun 18 #Javascript
javascript背景时钟实现方法
Jun 18 #Javascript
移动Web中图片自适应的两种JavaScript解决方法
Jun 18 #Javascript
javascript随机显示背景图片的方法
Jun 18 #Javascript
You might like
phpmyadmin config.inc.php配置示例
2013/08/27 PHP
初识php MVC
2014/09/10 PHP
PHP加密解密类实例分析
2015/04/20 PHP
CI框架实现cookie登陆的方法详解
2016/05/18 PHP
PHP表单验证内容是否为空的实现代码
2016/11/14 PHP
动态添加js事件实现代码
2009/03/12 Javascript
动态载入/删除/更新外部 JavaScript/Css 文件的代码
2010/07/03 Javascript
检测jQuery.js是否已加载的判断代码
2011/05/20 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
seaJs的模块定义和模块加载浅析
2014/06/06 Javascript
Javascript中arguments对象详解
2014/10/22 Javascript
js鼠标滑过图片震动特效的方法
2015/02/17 Javascript
javascript实现图片跟随鼠标移动效果的方法
2015/05/13 Javascript
Vue.js动态组件解析
2016/09/09 Javascript
微信小程序开发之Tabbar实例详解
2017/01/09 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
2017/11/28 Javascript
JS抛物线动画实例制作
2018/02/24 Javascript
vue-cli3使用 DllPlugin 实现预编译提升构建速度
2019/04/24 Javascript
Angular6使用forRoot() 注册单一实例服务问题
2019/08/27 Javascript
如何使用Javascript中的this关键字
2020/05/28 Javascript
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
Python的Bottle框架中返回静态文件和JSON对象的方法
2015/04/30 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
2017/09/26 Python
Python多线程多进程实例对比解析
2020/03/12 Python
Django+python服务器部署与环境部署教程详解
2020/03/30 Python
CSS3 实现的加载动画
2020/12/07 HTML / CSS
Maxpeedingrods美国:高性能汽车零件
2020/02/14 全球购物
CK澳大利亚官网:Calvin Klein澳大利亚
2020/12/12 全球购物
公务员个人自我评价分享
2013/11/06 职场文书
优秀团员事迹材料1000字
2014/08/20 职场文书
2014年商场国庆节活动策划方案
2014/09/16 职场文书
大一工商管理职业生涯规划:有梦最美,行动相随
2014/09/18 职场文书
介绍信范文
2015/01/31 职场文书
企业爱心捐款倡议书
2015/04/27 职场文书
敬老院活动感想
2015/08/07 职场文书
MySQL 字符集 character
2022/05/04 MySQL