Detailed description of nodejs acl user permission management, nodejsacl

Source: Internet
Author: User

Detailed description of nodejs acl user permission management, nodejsacl

Description

Q: What is this tool used?

A: users have different permissions, such as the administrator, vip, and common users. Each user accesses an api on different pages.

Nodejs has two well-known permission management modules. One is acl, and the other is rbac. After a comprehensive comparison, the acl is selected during project creation.

Function list:

  1. AddUserRoles // Add a role to a user
  2. RemoveUserRoles // remove a User Role
  3. UserRoles // obtain all roles of a user
  4. RoleUsers // obtain all users with this role
  5. HasRole // whether a user is a role
  6. AddRoleParents // Add a parent role to a role
  7. RemoveRoleParents // remove a parent role or all parent roles
  8. RemoveRole // remove a role
  9. RemoveResource // remove a resource
  10. Allow // Add some permissions for some resources to some roles
  11. RemoveAllow // remove some permissions for certain resources of certain roles
  12. AllowedPermissions // query all resources of a person and their Permissions
  13. IsAllowed // query whether a person has certain permissions for a resource.
  14. AreAnyRolesAllowed // query whether a role has a certain resource permission.
  15. WhatResources // query resources of a role
  16. Middleware // middleware for express
  17. Backend // specify the mode (mongo/redis ...)

ACL nouns and their main methods

Roles role

  1. RemoveRole
  2. AddRoleParents
  3. Allow
  4. RemoveAllow

Resources

  1. WhatResources
  2. RemoveResource

Permissions permission

Users user

  1. AllowedPermissions
  2. IsAllowed
  3. AddUserRoles
  4. RemoveUserRoles
  5. UserRoles
  6. RoleUsers
  7. HasRole
  8. AreAnyRolesAllowed

Usage

  1. Create a configuration file
  2. After logon, the user is assigned the corresponding permissions.
  3. Use acl for verification where control is needed

Configuration File

Const Acl = require ('acl'); const aclConfig = require ('.. /conf/acl_conf '); module. exports = function (app, express) {const acl = new Acl (new Acl. memoryBackend (); // eslint-disable-line acl. allow (aclConfig); return acl ;}; // acl_confmodule.exports = [{roles: 'normal', // common user allows: [{resources: ['/admin/reserv'], permissions: ['get']},]}, {roles: 'member', // member allows: [{resources: ['/admin/reserv','/admin/sign'], permissions: ['get']}, {resources: ['/admin/reserve/add-visitor ', '/admin/reserve/add-visitor-excel', '/admin/reserve/audit', '/admin/sign/ban'], permissions: ['post']},]}, {roles: 'admin', // manage allows: [{resources: ['/admin/reserv ', '/admin/sign','/admin/set'], permissions: ['get']}, {resources: ['/admin/set/add-user ', '/admin/set/modify-user'], permissions: ['post']},]}, {roles: 'root', // maximum permission allows: [{resources: ['/admin/reserv','/admin/sign', '/admin/set'], permissions: ['get']},]}];

School Inspection

Here is a school check in conjunction with express... the result shows that the middleware provided by the acl itself is too bad. Here we rewrite one.

Function auth () {return async function (req, res, next) {let resource = req. baseUrl; if (req. route) {// normally, the route attribute is used in the control but the app is used. use does not have resource = resource + req. route. path;} console. log ('resource', resource); // fault tolerance if/admin/sign/is accessed, it is also identified as if (resource [resource. length-1] = '/') {resource = resource. slice (0,-1);} let role = await acl. hasRole (req. session. userName, 'root'); I F (role) {return next ();} let result = await acl. isAllowed (req. session. userName, resource, req. method. toLowerCase (); // if (! Result) {// let err = {// errorCode: 401, // message: 'user unauthorized access', //}; // return res. status (401 ). send (err. message); //} next ();};}

It should be noted that express. the Router module can be exported to the app. use, but if you use the app in this way. use ('/admin/user', auth (), userRoute); then the req cannot be obtained in the auth function. route. Because acl strongly matches access permissions, it must be fault tolerant.

Logon permission allocation

The result is the user information queried by the database, or the user information returned by the background api. The switch here can be in the form of a configuration file, because I have only three permissions for this project, so I simply wrote it here.

let roleName = 'normal';  switch (result.result.privilege) {    case 0:      roleName = 'admin';      break;    case 1:      roleName = 'normal';      break;    case 2:      roleName = 'member';      break;  }  if (result.result.name === 'Nathan') {    roleName = 'root';  }  req.session['role'] = roleName;  // req.session['role'] = 'root';  // test  acl.addUserRoles(result.result.name, roleName);  // acl.addUserRoles(result.result.name, 'root'); // test

Rendering logic control in pug pages

In express + pug app. locals. auth = async function () {} does not get the final result during pug rendering, because pug is synchronous, how can I control whether the button user on the current page or the current page has the permission to display it? The common practices here are:

  1. When you log on, you have a route table and component table, which are then rendered based on the table during rendering.
  2. Where permission control is required, use a function to determine whether a user has access permissions.

I am using the Final Solution 2. it is convenient, but the problem is that express + pug does not support asynchronous writing, while acl provides us with asynchronous writing. Due to time reasons, I did not go into the judgment, however, a high coupling but convenient judgment method is adopted.

App. locals. hasRole = function (userRole, path, method = 'get') {if (userRole = 'root') {return true;} const current = aclConf. find (n) => {return n ['roles '] = userRole;}); let isFind = false; for (let I of current. allows) {const currentPath = I. resources; // The first in the current array is the simple get route isFind = currentPath. includes (path); if (isFind) {// if the path is found and the method corresponds to it, then the if (I. permissions. includes (method) {break;} // if the path is found but the method does not match, continue to find it. continue ;}} return isFind ;};

The above code page is relatively simple. Traverse acl_conf to check whether the user has the permission to access the current page or the button. Because acl_conf has been written into the memory during loading, the performance consumption will not be very high. For example, the following example.

If hasRole (user. role, '/admin/reserve/audit', 'post'). col. l3.right-align a.waves-effect.wav es-light.btn.margin-right.blue.font12.js-reviewe-ok agrees that the.waves-effect.wav es-light.btn.pink.accent-3.font12.js-reviewe-no rejects

End

Using the acl component, you can quickly create a user permission management module. However, there is another problem: the app. locals. hasRole function. If you use removeAllow to dynamically change the user's permission table, the hasRole function will be very troublesome. Therefore, the following solutions are available in this case:

  1. Starting with the acl source code
  2. Prepare the data for each rendering.
const hasBtn1Role = hasRole(user.role, '/xxx','get');res.render('a.pug',{hasBtn1Role})

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

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.