Maison  >  Article  >  interface Web  >  Explication détaillée de la gestion des droits d'utilisateur de nodejs acl

Explication détaillée de la gestion des droits d'utilisateur de nodejs acl

亚连
亚连original
2018-05-30 11:13:362674parcourir

Cet article présente principalement l'explication détaillée de la gestion des droits utilisateur de nodejs acl. Maintenant, je le partage avec vous et le donne comme référence.

Instructions

Q : À quoi sert cet outil

A : Les utilisateurs ont des autorisations différentes, telles que l'administrateur, le VIP, les utilisateurs ordinaires, chaque utilisateur accède à l'API et la page est différente

Nodejs dispose de deux modules de gestion des autorisations bien connus, l'un est acl et l'autre est rbac Après une comparaison complète, j'ai finalement choisi acl lorsque je travaillais sur le projet.

Liste des fonctions :

  1. addUserRoles //Ajouter un rôle à un utilisateur

  2. removeUserRoles / /Supprimer un certain rôle d'utilisateur

  3. userRoles //Obtenir tous les rôles d'un certain utilisateur

  4. roleUsers //Obtenir tous les utilisateurs avec ce rôle

  5. hasRole // Si un utilisateur est un certain rôle

  6. addRoleParents //Ajouter un rôle parent à un certain rôle

  7. removeRoleParents //Supprimer un certain rôle parent ou tous les rôles parents d'une certaine personne

  8. removeRole //Supprimer un certain rôle

  9. removeResource //Supprimer une certaine ressource

  10. allow //Ajouter certaines autorisations pour certaines ressources à certains rôles

  11. removeAllow //Supprimer certaines autorisations pour certains rôles Certaines autorisations pour certaines ressources

  12. allowedPermissions // Interroger toutes les ressources et autorisations de quelqu'un

  13. isAllowed // Demander si quelqu'un est Avoir une certaine autorisation pour une certaine ressource

  14. areAnyRolesAllowed // Demander si un certain rôle a une certaine autorisation pour une certaine ressource

  15. whatResources //Requête si un certain rôle dispose d'une certaine autorisation Quelles ressources

  16. middleware //middleware pour express

  17. backend //Méthode de spécification (mongo /redis...)

Noms ACL et leurs principales méthodes

rôles rôles

  1. RemoveRole

  2. addRoleParents

  3. allow

  4. removeAllow

ressources ressources

  1. whatResources

  2. removeResource

autorisations autorisations

utilisateurs utilisateurs

  1. allowedPermissions

  2. isAllowed

  3. addUserRoles

  4. supprimerUserRoles

  5. userRoles

  6. roleUsers

  7. hasRole

  8. areAnyRolesAllowed

Comment utiliser

  1. Créer un fichier de configuration

  2. Attribuez les autorisations correspondantes après la connexion de l'utilisateur

  3. Utilisez acl pour la vérification lorsque le contrôle est requis

Fichier de configuration

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_conf

module.exports = [
  {
    roles: 'normal', // 一般用户
    allows: [
      { resources: ['/admin/reserve'], permissions: ['get'] },
    ]
  },
  {
    roles: 'member', // 会员
    allows: [
      { resources: ['/admin/reserve', '/admin/sign'], permissions: ['get'] },
      { resources: ['/admin/reserve/add-visitor', '/admin/reserve/add-visitor-excel', '/admin/reserve/audit', '/admin/sign/ban'], permissions: ['post'] },
    ]
  },
  {
    roles: 'admin',  // 管理
    allows: [
      { resources: ['/admin/reserve', '/admin/sign', '/admin/set'], permissions: ['get'] },
      { resources: ['/admin/set/add-user', '/admin/set/modify-user'], permissions: ['post'] },
    ]
  },
  {
    roles: 'root', // 最高权限
    allows: [
      { resources: ['/admin/reserve', '/admin/sign', '/admin/set'], permissions: ['get'] },
    ]
  }
];

Relecture

Il s'agit d'une relecture combinée avec express... Il s'est avéré que le middleware fourni par acl lui-même était trop inutile, alors j'en ai réécrit un ici.

function auth() {
    return async function (req, res, next) {
      let resource = req.baseUrl;
      if (req.route) { // 正常在control中使用有route属性 但是使用app.use则不会有
        resource = resource + req.route.path;
      }
      console.log('resource', resource);

      // 容错 如果访问的是 /admin/sign/ 后面为 /符号认定也为过
      if (resource[resource.length - 1] === '/') {
        resource = resource.slice(0, -1);
      }

      let role = await acl.hasRole(req.session.userName, 'root');

      if (role) {
        return next();
      }

      let result = await acl.isAllowed(req.session.userName, resource, req.method.toLowerCase());
      // if (!result) {
      //   let err = {
      //     errorCode: 401,
      //     message: '用户未授权访问',
      //   };
      //   return res.status(401).send(err.message);
      // }
      next();
    };
  }

Une chose à noter est qu'express.Router prend en charge l'exportation d'un module de routeur, puis son utilisation dans app.use, mais si vous utilisez app. use( '/admin/user',auth(), userRoute); Alors l'attribut req.route ne peut pas être obtenu dans la fonction auth. Étant donné que acl correspond fortement aux autorisations d'accès, il doit avoir une certaine tolérance aux pannes

Attribution des autorisations de connexion

le résultat est les informations utilisateur demandées dans la base de données, ou l'arrière-plan Les informations utilisateur renvoyées par l'API peuvent être utilisées ici sous la forme d'un fichier de configuration pour le commutateur. Parce que je n'ai que trois autorisations pour ce projet, je vais les écrire brièvement ici.

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

Contrôle logique de rendu dans la page pug

app.locals.auth dans express+pug = async function(){} Cette façon d'écrire ne produira pas le résultat final lorsque pug est rendu, car pug est synchrone, alors comment puis-je contrôler si la page actuelle ou l'utilisateur du bouton de la page actuelle a la permission de l'afficher ? C'est courant ici. Les méthodes incluent

  1. Lorsque l'utilisateur se connecte, il dispose d'une table de routage et d'une table de composants, puis effectue le rendu selon cette table lors du rendu

  2. Lorsque le contrôle des autorisations est requis, utilisez des fonctions pour déterminer si l'utilisateur a l'autorisation d'accéder à

J'utilise le plan de fin 2. Parce que c'est plus pratique, mais le Le problème est qu'express+pug n'est pas pris en charge. L'écriture asynchrone, et ce que acl nous fournit est entièrement asynchrone. Pour des raisons de temps, je n'ai pas approfondi le jugement à l'intérieur, mais j'ai adopté une méthode de jugement hautement couplée mais plus pratique

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; // 目前数组第一个为单纯的get路由
    isFind = currentPath.includes(path);

    if (isFind) {
      // 如果找到包含该路径 并且method也对应得上 那么则通过
      if (i.permissions.includes(method)) {
        break;
      }

      // 如果找到该路径 但是method对应不上 则继续找.
      continue;
    }
  }

  return isFind;
};

La page de codes ci-dessus est relativement simple. Elle parcourt acl_conf pour savoir si l'utilisateur dispose des autorisations pour la page ou le bouton actuel car acl_conf a déjà été écrit. dans la mémoire lors du chargement. La consommation de performances ne sera donc pas particulièrement importante. Comme l'exemple suivant.

if hasRole(user.role, '/admin/reserve/audit', 'post')
          .col.l3.right-align
            a.waves-effect.waves-light.btn.margin-right.blue.font12.js-reviewe-ok 同意
            a.waves-effect.waves-light.btn.pink.accent-3.font12.js-reviewe-no 拒绝

Fin

En vous appuyant sur le composant acl, vous pouvez créer rapidement un module de gestion des droits des utilisateurs. Mais il y a toujours un problème, à savoir la fonction app.locals.hasRole. Si vous utilisez RemoveAllow pour modifier dynamiquement la table des autorisations de l'utilisateur, la fonction hasRole sera très gênante. Donc dans ce cas il y a plusieurs solutions :

  1. Commencez par le code source acl

  2. Préparez les données à chaque rendu

const hasBtn1Role = hasRole(user.role, '/xxx','get');
res.render('a.pug',{hasBtn1Role})

Ce qui précède est ce que j'ai compilé pour vous. J'espère que cela vous sera utile à l'avenir.

Articles connexes :

Comment utiliser le plug-in de meilleur défilement dans Angular_AngularJS

Implémentation d'Angularjs entre les contrôleurs Résumé de exemples de méthodes de communication

Le code JavaScript implémente la fonction de prévisualisation du téléchargement des fichiers txt

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn