7

Tôi đang tạo một ứng dụng web sẽ đáp ứng hai yêu cầu cho người dùng. Lưu ý: Tôi mới sử dụng AngularJS làm nền tảng phát triển web.Làm thế nào để xử lý ủy quyền dựa trên vai trò trong AngularJS?

Giao diện người dùng - 1: Chức năng tìm kiếm nơi người dùng có thể tìm kiếm tài liệu và nghiên cứu cụ thể dựa trên tìm kiếm và bộ lọc từ khóa. Điều này đã được thực hiện bằng cách sử dụng MySQL để tìm nạp dữ liệu và hiển thị bằng AngularJS.

Giao diện người dùng - 2: Người dùng sẽ có tùy chọn tạo tài khoản trên ứng dụng web. Mục đích của tài khoản là:

  1. Lưu truy vấn tìm kiếm của họ.
  2. Nếu quản trị viên liên kết từng người dùng với một vai trò cụ thể, thì những người dùng đó sẽ có quyền truy cập vào các tùy chọn bổ sung như sửa đổi tài liệu có trong cơ sở dữ liệu cũng như tải lên tài liệu mới và lưu trữ các trang khác.

Câu hỏi của tôi:

Làm thế nào để xử lý dựa trên vai trò ủy quyền bằng AngularJS? Tôi không thể tìm ra cách tạo khuôn khổ liên quan đến các chức năng sau: - Người dùng có vai trò liên quan đến họ - Ngăn người dùng truy cập các trang hoặc chức năng không được liên kết với các vai trò đó

Tôi đã đọc trên vài bài viết SO cũng như hướng dẫn nhưng mọi hướng dẫn đều kết thúc với tác giả nói rằng ủy quyền dựa trên vai trò nên được xử lý ở phía máy chủ và tôi hiểu tại sao điều này là đúng. Nó sẽ là tuyệt vời nếu bất cứ ai có thể chỉ cho tôi để hướng dẫn hoặc viết-up có ủy quyền dựa trên vai trò thực hiện trên phía máy chủ cho AngularJS.

Cảm ơn!

Trả lời

10

Tôi sử dụng ủy quyền dựa trên vai trò trên chương trình phụ trợ cũng như trên giao diện người dùng. Kể từ khi tôi đang sử dụng giao diện người dùng-Router cho việc định tuyến, tài nguyên tốt nhất mà tôi tìm thấy (và cải thiện để nhu cầu của tôi) là bài viết này:

link hết hạn

Nếu bạn sử dụng giao diện người dùng Router, chắc chắn kiểm tra xem nó ra. Về cơ bản, bạn cần phải thiết lập bảo mật tuyến đường của mình và chặn tất cả các thay đổi tuyến đường. Bài viết cũng bao gồm một chỉ thị để ẩn các phần tử giao diện người dùng, nếu người dùng không có quyền truy cập vào nội dung đằng sau nó.


Chỉnh sửa: Thêm một số mã.

Trước tiên, bạn cần có quyền của người dùng được lưu trữ ở đâu đó, ví dụ:trên đối tượng người dùng đăng trên localStorage:

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

Sau đó, bạn có hai bộ phận quan trọng:

  • thị - để xác định xem yếu tố nên được hiển thị hay không dựa trên sự cho phép giao
  • dịch vụ - để xử lý uỷ quyền kiểm tra

Chỉ thị:

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

})(); 

Bạn cần đặt CSS để các thành phần có lớp hidden không hiển thị.

dịch vụ:

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

Bây giờ, bạn có thể sử dụng các chỉ thị để hiển thị/ẩn các yếu tố:

<a ui-sref="app.administration" class="btn btn-primary pull-right" access="admin">Administration</a> 

Tất nhiên điều này sẽ chỉ ẩn các yếu tố trong DOM, vì vậy bạn phải làm ủy quyền kiểm tra trên máy chủ quá.

Phần đầu tiên này được giải quyết để hiển thị/ẩn các phần tử trong giao diện người dùng nhưng bạn cũng có thể bảo vệ các tuyến ứng dụng.

Route định nghĩa:

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

và bây giờ chỉ cần kiểm tra cho phép trong $stateChangeStart kiện

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

})(); 
+0

Cảm ơn bạn @ sh-ado-w, tôi sẽ được thực hiện rằng giải pháp bạn đã đề cập ở trên . Tôi sẽ cho bạn biết nếu nó hoạt động ra hay không. – CalmWinds

+2

Liên kết không hoạt động nữa. Tốt hơn là đăng nội dung trong SO so với liên kết bên ngoài nội dung. – eabates

+1

Tôi đã thêm mã từ ứng dụng của mình, theo tôi, dựa trên bài viết đó. – Adrian

Các vấn đề liên quan