AngularJS – 實現基于角色訪問控制的 GUI

jopen 10年前發布 | 14K 次閱讀 JavaScript開發 angularjs

這些天我們忙于應用的前端工作,我們主要使用angular完成的。最近的一個需求是基于角色訪問GUI。一個用戶可以有多個角色,而它應只能訪問授權給他的那一部分GUI。
我們主要通過在2個層次限制應用的GUI訪問,來解決上述需求:

  1. 一個用戶只能訪問授權給他的頁面(或者說流量)

    </li>

  2. 在一個頁面上,用戶只能看到授權給他的那部分。

    </li> </ol>

    要解決上述需求1,我們捕捉路有變化事件并對每一路由變化進行檢查,看用戶是否授權訪問下一路由,保證他不會看到拒絕訪問的頁面

    $rootScope.$on("$routeChangeStart", function(event, next, current) {
        if(!authService.isUrlAccessibleForUser(next.originalPath))
        $location.path('/authError');
    });

    上面的authService 是我們創建的一個服務,它有角色用戶列表,并給授權用戶路由流量。函數isUrlAccessibleForUser() 將檢查分配的用戶是否可以訪問給定流量并返回true或false.

    服務將 從后臺和路由訪問信息中獲取一個用戶的角色列表,每個角色將保存在服務本身的一個Map集合中。(關于用戶和角色的一些細節可以存到數據局,通過后臺的方式獲取)

    app.factory('authService', function ($http) {

        var userRole = []; // obtained from backend     var userRoleRouteMap = {         'ROLE_ADMIN': [ '/dashboard', '/about-us', '/authError' ],         'ROLE_USER': [ '/usersettings', '/usersettings/personal', '/authError']     };

        return {

            userHasRole: function (role) {             for (var j = 0; j < userRole.length; j++) {                 if (role == userRole[j]) {                     return true;                 }             }             return false;         },

            isUrlAccessibleForUser: function (route) {             for (var i = 0; i < userRole.length; i++) {                 var role = userRole[i];                 var validUrlsForRole = userRoleRouteMap[role];                 if (validUrlsForRole) {                     for (var j = 0; j < validUrlsForRole.length; j++) {                         if (validUrlsForRole[j] == route)                             return true;                     }                 }             }             return false;         }     }; });</pre>

    這將解決上述需求的第一點,對于需求的第二點我們來創建一條指令。這個指令信息類似以下:

    <div my-access=”ROLE_ADMIN”>......</div>

    如果用戶有  ROLE_ADMIN 的這個角色的時候,將以上的html標簽將被加載到html的頁面中,否則將 這個 Html標簽從 頁面中移除。

    指令的實現代碼如下:

    .directive('myAccess', ['authService', 'removeElement', function (authService, removeElement) {
        return{
            restrict: 'A',
            link: function (scope, element, attributes) {

                var hasAccess = false;             var allowedAccess = attributes.myAccess.split(" ");             for (i = 0; i < allowedAccess.length; i++) {                 if (authService.userHasRole(allowedAccess[i])) {                     hasAccess = true;                     break;                 }             }

                if (!hasAccess) {                 angular.forEach(element.children(), function (child) {                     removeElement(child);                 });                 removeElement(element);             }

            }     } }]).constant('removeElement', function(element){     element && element.remove && element.remove(); });</pre>

    這一辦法是很簡潔的,而我們在GUI上很巧妙的實現了用戶授權. 一個潛在的問題是,如果UI的渲染器在你從后臺獲取用戶角色之前就已經在運行了,那么該HTML中所有帶上該指令的部分都會從html中被移除掉. 這對于我們而言不是個麻煩,因為我們會在登錄完成之時就獲取到了用戶角色的詳細信息。而如果這一問題對你而言是個問題的話,解決方案可以是這樣:如果用戶角色還沒有獲取到,就只是隱藏這些html元素,僅等到你獲取到角色列表之后再按照授權0信息將它們移除掉. 同時還請注意不能因為有了一個GUI的訪問控制,就省掉了后臺固有的安全實現.

    達者廣交,分享為先!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!