我正在创建一个Web应用程序,它将满足用户的两个要求。注意:我是 AngularJS 作为 Web 开发平台的新手。

前端 - 1:它是一个搜索功能,用户可以根据关键字搜索和过滤器搜索特定的文档和研究。这是使用 MySQL 实现的,用于使用 AngularJS 获取数据和显示。

前端 - 2:用户可以选择在 Web 应用程序上创建帐户。该帐户的目的是:

  • 保存他们的搜索查询。
  • 如果管理员将每个用户与特定 Angular 色相关联,那么这些用户将获得额外选项的访问权限,例如修改数据库中存在的文档以及上传新文档和其他页面的主机。

  • 我的问题:

    如何在 AngularJS 中处理基于 Angular 色的授权?我无法弄清楚如何创建一个涉及以下功能的框架:
    - 用户获得与其关联的 Angular 色
    - 防止用户访问与这些 Angular 色无关的页面或功能

    我已经阅读了一些 SO 文章和教程,但每个教程都以作者说基于 Angular 色的授权应该在服务器端处理,我明白为什么这是真的。

    如果有人能指点我在 AngularJS 的服务器端实现基于 Angular 色的授权的教程或文章,那就太好了。

    谢谢!

    最佳答案

    我在后端和前端使用基于 Angular 色的授权。由于我使用 UI-Router 进行路由,因此我发现(并根据我的需求进行了改进)的最佳资源是这篇文章:

    链接已过期

    如果你使用 UI Router,一定要检查一下。基本上,您需要设置路由安全性并拦截所有路由更改。如果用户无权访问其背后的内容,本文还包含用于隐藏用户界面元素的指令。

    编辑: 添加一些代码。

    首先,您需要将用户的权限存储在某处,例如在 localStorage 中序列化的用户对象上:

    {"id":1,"name":"user","created_at":"2016-04-17 18:58:19","gender":"m","roles":["admin"]}
    

    然后,您有两个重要部分:
  • 指令 - 根据分配的权限确定元素是否应该可见
  • 服务 - 处理授权检查

  • 指令:
    (function() {
      'use strict';
    
      angular
        .module('app')
        .directive('access', access);
    
      /** @ngInject */
      function access(authorization) {
        var directive = {
          restrict: 'A',
          link: linkFunc,
        };
    
        return directive;
    
        /** @ngInject */
        function linkFunc($scope, $element, $attrs) {
          var makeVisible = function () {
            $element.removeClass('hidden');
          };
    
          var makeHidden = function () {
            $element.addClass('hidden');
          };
    
          var determineVisibility = function (resetFirst) {
            var result;
    
            if (resetFirst) {
              makeVisible();
            }
    
            result = authorization.authorize(true, roles, $attrs.accessPermissionType);
    
            if (result === authorization.constants.authorised) {
              makeVisible();
            } else {
              makeHidden();
            }
          };
    
          var roles = $attrs.access.split(',');
    
          if (roles.length > 0) {
              determineVisibility(true);
          }
        }
      }
    
    })();
    

    您需要设置您的 CSS,以便类 hidden 的元素不可见。

    服务:
    (function() {
      'use strict';
    
      angular
        .module('app')
        .factory('authorization', authorization);
    
      /** @ngInject */
      function authorization($rootScope) {
        var service = {
          authorize: authorize,
          constants: {
            authorised: 0,
            loginRequired: 1,
            notAuthorised: 2
          }
        };
    
        return service;
    
        function authorize(loginRequired, requiredPermissions, permissionCheckType) {
          var result = service.constants.authorised,
              user = $rootScope.currentUser,
              loweredPermissions = [],
              hasPermission = true,
              permission;
    
          permissionCheckType = permissionCheckType || 'atLeastOne';
    
          if (loginRequired === true && user === undefined) {
              result = service.constants.loginRequired;
    
          } else if ((loginRequired === true && user !== undefined) &&
                      (requiredPermissions === undefined || requiredPermissions.length === 0)) {
              result = service.constants.authorised;
    
          } else if (requiredPermissions) {
    
              loweredPermissions = [];
    
              angular.forEach(user.roles, function (permission) {
                  loweredPermissions.push(permission.toLowerCase());
              });
    
              for (var i = 0; i < requiredPermissions.length; i += 1) {
                  permission = requiredPermissions[i].toLowerCase();
    
                  if (permissionCheckType === 'combinationRequired') {
                      hasPermission = hasPermission && loweredPermissions.indexOf(permission) > -1;
                      // if all the permissions are required and hasPermission is false there is no point carrying on
                      if (hasPermission === false) {
                          break;
                      }
                  } else if (permissionCheckType === 'atLeastOne') {
                      hasPermission = loweredPermissions.indexOf(permission) > -1;
                      // if we only need one of the permissions and we have it there is no point carrying on
                      if (hasPermission) {
                          break;
                      }
                  }
              }
    
              result = hasPermission ?
                       service.constants.authorised :
                       service.constants.notAuthorised;
          }
    
          return result;
        }
      }
    })();
    

    现在,您可以使用指令来显示/隐藏元素:
    <a ui-sref="app.administration" class="btn btn-primary pull-right" access="admin">Administration</a>
    

    当然,这只会隐藏DOM中的元素,因此您也必须在服务器上进行授权检查。

    第一部分解决了在用户界面中显示/隐藏元素的问题,但您也可以保护应用程序路由。

    路由定义:
    (function() {
      'use strict';
    
      angular
        .module('app')
        .config(routeConfig);
    
      /** @ngInject */
      function routeConfig($stateProvider) {
        $stateProvider
          .state('app.dashboard', {
            url: '/dashboard',
            data: {
              access: {
                loginRequired: true
              }
            },
            templateUrl: 'template_path',
            controller: 'DashboardController as vm'
          }
      }
    })();
    

    现在只需在 $stateChangeStart 事件中检查权限
    (function() {
      'use strict';
    
      angular
        .module('app')
        .run(runBlock);
    
      /** @ngInject */
      function runBlock($rootScope, $state, authorization) {
        $rootScope.$on('$stateChangeStart', function(event, toState) {
          // route authorization check
          if (toState.data !== undefined && toState.data.access !== undefined) {
            authorised = authorization.authorize(toState.data.access.loginRequired,
                                                 toState.data.access.requiredPermissions,
                                                 toState.data.access.permissionCheckType);
    
            if (authorised === authorization.constants.loginRequired) {
              event.preventDefault();
              $state.go('app.login');
            } else if (authorised === authorization.constants.notAuthorised) {
              event.preventDefault();
              $state.go('app.dashboard');
            }
          }
        });
      }
    
    })();
    

    关于mysql - 如何在 AngularJS 中处理基于 Angular 色的授权?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33374328/

    10-13 08:48