Permissions in my opinion refer to whether a user has access to an interface. On the front end, even if a user visits a page he or she is not supposed to see, he or she does not have access to the interface, so that even if he or she enters the page, he or she cannot see the corresponding data. But what we want to do in the front end is to let the user access this page, directly receive a prompt, no permission.

However, in many projects, page routing is now managed by the front end. How to do this, I will share the solution I used in previous projects.

I wrote a demo and uploaded it to Github with the address admin-permission-demo

How are database tables designed

When I first started working with the back end on this requirement, I felt overwhelmed and at a loss what to do. I had no idea how permission control worked, or that permission meant restricting user access to an interface. So before WE start, I think it’s worth saying a little bit about how the permission table is designed. Our project uses RBAC, which is simply three things: users, roles, and permissions (resources). I’m not going to bother drawing a picture, I’m just going to use a picture that someone else has drawn.

This permission is the interface in the project, so the meaning is obvious. You specify which interfaces a role can access and then assign roles to users. This allows users to control which interfaces they can and cannot access.

Menu and button permissions

The general appearance of the permission table in our project:

id p_id type permission name
The primary key ID The parent ID Type: menu or button Permission to identify The name of the

Permissions are divided into menu permissions and button permissions. What does that mean?

For example, we now want to develop a page, called user management, in user management this page will carry out some operations to add and delete users. I refer to this user management as menu permissions, and the operations below it are called button permissions. The p_ID of these interfaces is obviously the primary key ID of this menu permission.

[{p_id: ' '.id: 1000.name: 'Permission Management'.type: 1./ / the menu
    permission: 'permission_manage'.children: [{p_id: 1000.id: 1100.name: 'User Management'.type: 1./ / the menu
        permission: 'user_manage'.children: [{p_id: 110.id: 1101.name: 'Add user'.type: 2./ / button}... ] }}]]Copy the code

How, such data structure is not very familiar, is not the left menu in the management system. This menu permission is what the front end uses when it comes to page access control. This data structure is just the way I wrote it to make it easier to understand. In my project, the permission data I found in the back end does not look like this, it is just an array, each item is data, no grouping operation (i.e. no children). In this way, after the front end gets the data, it can be integrated into menu permission set and button permission set according to type, which is convenient for subsequent use.

Front-end code to achieve access control

Now that you understand how permissions are designed, let’s talk about how the front-end code implements them.

My past projects have used React + ANTd + dVA + typescript. In fact, it doesn’t matter what technology the front end chooses, the important thing is that the idea is understood, and the rest is just different code implementation.

First, I will ask the backend to provide me with an interface to query all permissions of the current user. Then I’ll divide it into menu permissions and button permissions and use Redux to manage it.

Render left menu

First, render the left menu. In a project, there is usually a special configuration file for the left menu, which defines the menu name, icon, page path, and so on. Some menu pages need to be managed by permissions, while others don’t. For pages that need to be managed by permissions I will add a field called menu identity.

  interface MenuDataItem {
    name: string;  // Menu nameicon? :string;
    path: string; children? :Array<MenuDataItem>; permission? :string;  // Menu identifier
  }
  constmenuData: MenuDataItem[] = [...] ;Copy the code

The left menu in the project will be rendered according to the menuData. The logic here is to first see if the menu has a menu identifier, and then render it if it doesn’t. If there is a menu identifier, it depends on whether the user has the menu permission. If there is, it will render, and if there is no, it will not render. The structure of each project is definitely different, SO I will not post any codes. What is important is the idea. I wrote a demo for the specific implementation and uploaded it to Github.

Routing level control

It’s definitely not enough to just manage the rendering of the left menu, you need to control it at the routing level. In react, routing is also a component, so you can control the route rendering. Vue configures the router globally, so restrict it in the route guard. Similarly, the page corresponds to the menu routing to see whether the user has the menu permission. If the user does not have the menu permission, the page will be displayed normally.

Button level controls

Or take user management to take an example, add, delete, check, change. A user may only have the permission to delete, query, or modify a file but not to add a file. At this time in the page should not render “add user” such a button, otherwise the user data input for a long time, a request to the back end of a check prompt insufficient authority embarrassment, I can not do this operation, you also show me what to do?

Write a component that doesn’t matter what it’s called, like a PermissionButton. React passes the original button to the component as children, vue would say

. The component also receives props, which is an array and is called permissions. Each entry in this array is a button permission identifier, representing which permissions are required to display the button, or perhaps one of them. Provide props to control the function, with the value every or some. “Every” means “all” and “some” means “all”.

Then it’s time to check the user’s button permissions. If you have the reconfigurable component, show the original component. If you don’t, don’t show it.

conclusion

This is my background management system accumulated a little practice. If you have a better plan, or feel where can be improved, welcome to exchange.

Users of VUE may not be very friendly. Because demo is implemented with React. However, I don’t see much difference between react and Vue. If I have the opportunity to use VUE in my work later, I will use the Vue demo in the update version. The most important thing to understand is that this permission is also simple. I hope I can help people in need.

The specific implementation is certainly not a few lines of code can be pasted clearly, how the code is also related to the specific project structure.

I provided a demo and uploaded it to Github with the address admin-permission-demo.

Demo is also based on my own management system template to do, the address is: ANTD-admin