使用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();
      }
    }
  };
});

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]);
          },
        }
      });
  });
时间: 2015-06-15

AngularJS中的路由使用及实现代码

前  言 本章节将为大家介绍 AngularJS 路由.AngularJS 路由允许我们通过不同的 URL 访问不同的内容.通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA). 1.1 Angular JS路由基础知识讲解 在AngularJS中使用路由: 1. 导入路由文件:angular-route.js 2. 在主模块中注入"ngRoute". angular.module("app",[

AngularJS路由实现页面跳转实例

AngularJS是一个javascript框架,通过AngularJS这个类库可以实现目前比较流行的单页面应用,AngularJS还具有双向数据绑定的特点,更加适应页面动态内容. 所谓单页面应用就是在同一个页面动态加载不同的内容,而这里的"跳转"可以理解为是局部页面的跳转. AngularJS是通过改变location地址来实现加载不同的页面内容到指定位置,下面是一个简单应用AngularJS路由来实现页面"跳转"的实例: 使用app.config来定义不同的lo

AngularJS监听路由的变化示例代码

话不多说,我们下面直接来看实现的示例代码 [一]Angular 路由状态发生改变时可以通过' $stateChangeStart '.' $stateChangeSuccess '.' $stateChangeError '监听,通过注入'$location'实现状态的管理 代码示例如下: function run($ionicPlatform, $location, Service, $rootScope, $stateParams) { //路由监听事件 $rootScope.$on('$s

angular.js 路由及页面传参示例

页面传参数方法:1.$rootScope.2.(url)/user/:name/:age. 页面转换方法:1.href="#/" rel="external nofollow" rel="external nofollow" rel="external nofollow" .2.$state.Go.3.$location.path.4.ui-sref (1)自带路由ngRoute <html> <head&g

AngularJS 路由详解和简单实例

AngularJS 路由 本章节我们将为大家介绍 AngularJS 路由. AngularJS 路由允许我们通过不同的 URL 访问不同的内容. 通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA). 通常我们的URL形式为 http://runoob.com/first/page,但在单页Web应用中 AngularJS 通过 # + 标记 实现,例如: http://runoob.com/#/first http://r

angular.js之路由的选择方法

在一个单页面中,我们可以添加多个模块,使得网页只在需要的时候加载这个模块.模块的切换大致上可以代替网页的切换,于是,我们便可以通过模块的切换实现网页的切换,这个切换是按需加载的. 乍一看非常普通的东西,但是仔细想想就可以发现,这种思想可以解决非常多的资源. 例如,假如有一个页面,需要显示1000种商品的信息,每个商品的表现形式各不相同(设他们有各自独立的css和js),那么一般来说,我们就需要准备1000张网页去加载这些信息.但是,使用这种模块化思想,我们就可以仅仅在后台设定1000个各不相同的

详解Angular4中路由Router类的跳转navigate

最近一直在学习angular4,它确实比以前有了很大的变化和改进,好多地方也不是那么容易就能理解,好在官方的文档和例子是中文,对英文不太好的还是有很大帮助去学习. 官方地址:https://angular.cn/docs/ts/latest/api/router/index/Router-class.html 在学习的过程中路由(router)机制是离不开的,并且好多地方都要用到. 首先路由配置Route: import { NgModule } from '@angular/core'; im

Angularjs制作简单的路由功能demo

从官网下载了最新版本的Angularjs 版本号:1.3.15 做一个简单的路由功能demo 首页:index.html <!DOCTYPE html > <html> <head> <meta charset="utf-8" /> <title>测试</title> <script src="./js/angular.min.js"></script> <scri

AngularJS 路由和模板实例及路由地址简化方法(必看)

最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽,其中爽就爽在它的开发模式,使得代码更加的清晰.更加具有可读性.更简洁.更具有维护性.但是在使用AngularJS开发的过程中也有让我头疼的地方,那就是目前前端框架更多的还是以Jquery为主,很多插件都是依赖于Jquery的,AngulaJS的插件少之又少(除了AngularUI其他的Angula

AngularJS监听路由变化的方法

使用AngularJS时,当路由发生改变时,我们需要做某些处理,此时可以监听路由事件,常用的是$routeStartChange, $routeChangeSuccess.完整例子如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"

vue.js使用watch监听路由变化的方法

watch除了可以监听数据的变化,路由的变化也能被其监听到 效果如下: 具体代码 当路由发生变化后,在watch中写具体的业务逻辑 let vm = new Vue({ el: "#app", data: {}, router, watch: { '$route.path': function (newVal, oldVal) { if (newVal === '/login') { console.log('欢迎进入登录页面'); } if (newVal === '/registe

AngularJS 监听变量变化的实现方法

如下所示: var timeout; $scope.$watch('search.subj',function (newVal, oldVal) { if (newVal !== oldVal) { if (timeout) $timeout.cancel(timeout); timeout = $timeout(function() { $scope.doSearch(); }, 800); } }, true); 以上这篇AngularJS 监听变量变化的实现方法就是小编分享给大家的全部内容

vue在App.vue文件中监听路由变化刷新页面操作

在路由跳转时,会出现页面需要重新刷新一遍才能获取数据加载页面,这时添加一个监听器,如果跳转到页面刷新一次. export default { name: 'App', provide(){ return{ reload:this.reload } }, data(){ return { isRouterAlive:true, } }, //监听器 watch: { // 方法1 '$route' (to, from) { //监听路由是否变化 // console.log(999) if(to.

Android编程实现监听EditText变化的方法

本文实例讲述了Android编程实现监听EditText变化的方法.分享给大家供大家参考,具体如下: 监听EditText中的内容的变化.在EditText没有找到一个setOnxxxx的方法.百度了一下,原来在EditText中有一个方法addTextChangedListner(TextWatcher watcher)方法,用他可以时时监听EditText的内容变化.TextWatcher是一个接口类,所以必须实现TextWatcher里的抽象方法: 当EditText里面的内容有变化的时候

使用watch监听路由变化和watch监听对象的实例

一.watch监听路由变化 解决办法: export default{ data(){ return{} }, watch:{ "$route":"getPath" // 监听事件 }, methods:{ getPath(){ let path = this.$roune.path; //或得当前路径 进行逻辑判断 } } } 二.watch监听对象 例子: <el-select v-model="form.region" placeho

vue自定义键盘信息、监听数据变化的方法示例【基于vm.$watch】

本文实例讲述了vue自定义键盘信息.监听数据变化的方法.分享给大家供大家参考,具体如下: @keydown.up @keydown.enter @keydown.a/b/c.... 自定义键盘信息: Vue.directive('on').keyCodes.ctrl=17; Vue.directive('on').keyCodes.myenter=13; @keydown.a/b/c.... <input type="text" @keydown.c="show&quo

React和Vue中监听变量变化的方法

React 中 本地调试React代码的方法 yarn build 场景 假设有这样一个场景,父组件传递子组件一个A参数,子组件需要监听A参数的变化转换为state. 16之前 在React以前我们可以使用 componentWillReveiveProps 来监听 props 的变换 16之后 在最新版本的React中可以使用新出的 getDerivedStateFromProps 进行props的监听, getDerivedStateFromProps 可以返回 null 或者一个对象,如果

小程序使用watch监听数据变化的方法详解

众所周知,Vue中,可以使用监听属性 watch来观察和响应 Vue 实例上的数据变化,那么小程序能不能实现这一点呢? 监听器的原理,是将data中需监听的数据写在watch对象中,并给其提供一个方法,当被监听的数据的值改变时,调用该方法.​​ 我们需要用到Javascript中的Object.defineProperty()方法,来手动劫持对象的getter/setter,从而实现给对象赋值时(调用setter),执行watch对象中相对应的函数,达到监听效果. Object.definePr