设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

AngularJS路由的安全性处理

2014-9-1 14:59| 发布者: joejoe0332| 查看: 5556| 评论: 0|原作者: daxiang, 开源中国匿名会员|来自: oschina

摘要: 自从出现以后,AngularJS已经被使用很长时间了。 它是一个用于开发单页应用(SPA)的javascript框架。 它有一些很好的特性,如双向绑定、指令等。 这篇文章主要介绍Angular路由安全性策略。 它是一个可用Angular开发实 ...

简介

  自从出现以后,AngularJS已经被使用很长时间了。 它是一个用于开发单页应用(SPA)的javascript框架。 它有一些很好的特性,如双向绑定、指令等。 这篇文章主要介绍Angular路由安全性策略。 它是一个可用Angular开发实现的客户端安全性框架。 我已经对它进行了测试。 除了保证客户端路由安全性外,你也需要保证服务器端访问的安全性。 客户端安全性策略有助于减少对服务器进行额外的访问。 然而,如果一些人采用欺骗浏览器的手段访问服务器,那么服务器端安全性策略应当能够拒绝未授权的访问。 在这篇文章中,我仅对客户端安全性策略进行讨论。


1 哒哒: 在应用模块层面定义全局变量

为应用定义角色:

1
2
3
4
5
var roles = {
    superUser: 0,
    admin: 1,
    user: 2
};

为应用定义未授权访问的路由:

1
var routeForUnauthorizedAccess = '/SomeAngularRouteForUnauthorizedAccess';

2 哒哒: 定义授权服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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 哒哒: 加密路由

然后让我们用我们的努力成果来加密路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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]);
                    },
                }
            });
    });

酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部