Angular implements permission control in the frontend and backend separation mode-Based on RBAC (1)

Source: Internet
Author: User

Angular implements permission control in the frontend and backend separation mode-Based on RBAC (1)

Role-Based Access Control (RBAC) is a common design of permissions. The basic idea is that permissions for system operations are not directly granted to specific users, instead, a role set is created between the user set and the permission set. Each role corresponds to a group of permissions.

Once a user is assigned an appropriate role, the user has all operation permissions for this role. The advantage of this is that you do not have to assign permissions each time you create a user. You only need to assign the corresponding role to the user, and the permission change of the role is much less than that of the user, this will simplify user permission management and reduce system overhead.

In a single page application built by Angular, we need to do more to implement such an architecture. In terms of the overall project, there are about three places where front-end engineers need to deal with it.

1. UI processing (based on the user's permissions, determine whether some content on the page is displayed)

2. Route processing (when a user accesses a url that he or she does not have the permission to access, he or she jumps to an error prompt page)

3. HTTP request processing (when we send a data request, if the returned status is 401 or 401, it is usually redirected to an error page)

How to implement it?

First, you need to obtain all the permissions of the current user before Angular starts. Then, you can store the ing through a service in an elegant way. whether the content on a page processed by the UI is displayed based on permissions should be implemented through a direve ve. after processing this, we also need to add a "permission" attribute to a route, and assign a value to it to indicate which permissions the role can jump to this URL, then, Angular listens to the routeChangeStart event to verify whether the current user has the access permission for this URL. finally, an HTTP interceptor is required to monitor the status returned by a request, which is 401 or 403.

In general, the work seems to be a little more, but it is quite easy to handle it one by one.

Get the permission ing before Angular runs.

The Angular project is started through ng-app, but in some cases we want the Angular project to be started under our control. for example, in this case, I want to get all the permission mappings of the currently logged-on user and then start the Angular App. fortunately, Angular provides this method, that is, angular. bootstrap ().

 
 
  1. var permissionList;  
  2. angular.element(document).ready(function() {  
  3.   $.get('/api/UserPermission', function(data) {  
  4.     permissionList = data;  
  5.     angular.bootstrap(document, ['App']);  
  6.   });  
  7. }); 

You may notice that $ is used here. get (). jQuery is not the $ resource or $ http of Angular, because Angular has not been started yet and its function cannot be used yet.

The above code can be further used to put the obtained ing relationship into a service as a global variable.

 
 
  1. // app.js  
  2. var app = angular.module('myApp', []), permissionList;  
  3.     
  4. app.run(function(permissions) {  
  5.   permissions.setPermissions(permissionList)  
  6. });  
  7.     
  8. angular.element(document).ready(function() {  
  9.   $.get('/api/UserPermission', function(data) {  
  10.     permissionList = data;  
  11.     angular.bootstrap(document, ['App']);  
  12.   });  
  13. });  
  14.    
  15. // common_service.js  
  16. angular.module('myApp')  
  17.   .factory('permissions', function ($rootScope) {  
  18.     var permissionList;  
  19.     return {  
  20.       setPermissions: function(permissions) {  
  21.         permissionList = permissions;  
  22.         $rootScope.$broadcast('permissionsChanged')  
  23.       }  
  24.    };  
  25.   }); 

After obtaining the permissions set of the current user, We archive the set to the corresponding service, and then did two things:

(1) store permissions in the factory variable to keep it in the memory, so as to implement the global variable, but it does not pollute the namespace.

(2) broadcast events through $ broadcast when the permissions are changed.

How to determine the explicit permission of the UI component

Here we need to write a direve ve by ourselves, which will display or hide elements based on the permission relationship.

 
 
  1. <!-- If the user has edit permission the show a link -->  
  2. <div has-permission='Edit'>  
  3.   <a href="/#/courses/{{ id }}/edit"> {{ name }}</a>  
  4. </div>  
  5.     
  6. <!-- If the user doesn't have edit permission then show text only (Note the "!" before "Edit") -->  
  7. <div has-permission='!Edit'>  
  8.   {{ name }}  
  9. </div> 

Here we can see that the ideal situation is to pass through an has-permission attribute to verify the permission name. If the current user has one, it will be displayed. If not, it will be hidden.

 
 
  1. angular.module('myApp').directive('hasPermission', function(permissions) {  
  2.   return {  
  3.     link: function(scope, element, attrs) {  
  4.       if(!_.isString(attrs.hasPermission))  
  5.         throw "hasPermission value must be a string";  
  6.     
  7.       var value = attrs.hasPermission.trim();  
  8.       var notPermissionFlag = value[0] === '!';  
  9.       if(notPermissionFlag) {  
  10.         value = value.slice(1).trim();  
  11.       }  
  12.     
  13.       function toggleVisibilityBasedOnPermission() {  
  14.         var hasPermission = permissions.hasPermission(value);  
  15.     
  16.         if(hasPermission && !notPermissionFlag || !hasPermission && notPermissionFlag)  
  17.           element.show();  
  18.         else 
  19.           element.hide();  
  20.       }  
  21.       toggleVisibilityBasedOnPermission();  
  22.       scope.$on('permissionsChanged', toggleVisibilityBasedOnPermission);  
  23.     }  
  24.   };  
  25. }); 

Extend the previous factory:

 
 
  1. angular.module('myApp')  
  2.   .factory('permissions', function ($rootScope) {  
  3.     var permissionList;  
  4.     return {  
  5.       setPermissions: function(permissions) {  
  6.         permissionList = permissions;  
  7.         $rootScope.$broadcast('permissionsChanged')  
  8.       },  
  9.       hasPermission: function (permission) {  
  10.         permission = permission.trim();  
  11.         return _.some(permissionList, function(item) {  
  12.           if(_.isString(item.Name))  
  13.             return item.Name.trim() === permission  
  14.         });  
  15.       }  
  16.    };  
  17.   }); 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.