npm 包 node-rbac 使用教程

前言

在现代开发中,权限控制是不可或缺的一部分,它能够有效地保护系统和用户的安全。而在运用权限控制时,基于角色的访问控制(Role-Based Access Control,RBAC)是一种广泛使用的方法,它将权限控制与角色、用户、资源进行关联,从而达到灵活且易于管理的效果。

在 Node.js 平台上,我们可以使用 node-rbac 包来实现 RBAC,它是一个可轻松配置、灵活的包。

本文将详细介绍 npm 包 node-rbac 的使用教程,内容包括示例代码、深度思考等。

安装

使用 npm 包管理器:

npm install node-rbac --save

基础使用

1. 创建 RBAC 实例

在代码中引入 node-rbac 包并创建 RBAC 实例:

const RBAC = require('node-rbac');

const rbac = new RBAC();

2. 创建角色和权限

我们需要在代码中指定应用的角色和权限:

rbac.createRole('guest')            // 创建角色 guest 
    .createPermission('article:view') // 给角色 guest 创建 article:view 权限
    .createPermission('article:add')  // 给角色 guest 创建 article:add 权限

rbac.createRole('member')            // 创建角色 member 
    .createPermission('article:view') // 给角色 member 创建 article:view 权限
    .createPermission('article:add')  // 给角色 member 创建 article:add 权限
    .createPermission('article:edit') // 给角色 member 创建 article:edit 权限

rbac.createRole('admin')            // 创建角色 admin 
    .createPermission('article:view') // 给角色 admin 创建 article:view 权限
    .createPermission('article:add')  // 给角色 admin 创建 article:add 权限
    .createPermission('article:edit') // 给角色 admin 创建 article:edit 权限
    .createPermission('article:delete'); // 给角色 admin 创建 article:delete 权限

3. 指定角色用户

我们需要在代码中指定每个用户对应的角色:

rbac.grant('guest', 'user:123');  // 用户 user:123 的角色为 guest
rbac.grant('member', 'user:456'); // 用户 user:456 的角色为 member
rbac.grant('admin', 'user:789');  // 用户 user:789 的角色为 admin

4. 检查用户权限

在运用 RBAC 实现权限控制时,我们可以检查指定用户是否有指定权限:

const userID = 'user:456';
const permission = 'article:add';
const hasPermission = rbac.check(userID, permission);

console.log(hasPermission); // true

深度思考

1. 数据库中存储 RBAC

在实际应用中,我们往往将 RBAC 数据存储在数据库中,这样做有助于扩展和灵活性。接下来以 MongoDB 为例,介绍如何存储 RBAC 数据。

首先在 MongoDB 中创建一个名为 rbac 的数据库,并创建 rolespermissions 集合,如下所示:

use rbac;

db.createCollection("roles");

db.roles.insertMany([
  { name: "guest", permissions: ["article:view", "article:add"] },
  { name: "member", permissions: ["article:view", "article:add", "article:edit"] },
  { name: "admin", permissions: ["article:view", "article:add", "article:edit", "article:delete"] }
]);

db.createCollection("permissions");

db.permissions.insertMany([
  { name: "article:view" },
  { name: "article:add" },
  { name: "article:edit" },
  { name: "article:delete" }
]);

接着,我们需要在应用代码中获取 MongoDB 数据,并将其转换为 RBAC 实例:

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
const dbName = 'rbac';

const client = new MongoClient(url, { useNewUrlParser: true });

client.connect(async function(err) {
  if (err) throw err;

  const db = client.db(dbName);

  const roles = await db.collection('roles').find().toArray();
  const permissions = await db.collection('permissions').find().toArray();

  const rbac = new RBAC();

  roles.forEach((role) => {
    rbac.createRole(role.name);
    role.permissions.forEach((permission) => {
      const p = permissions.find((p) => p.name === permission);
      rbac.createPermission(p.name);
      rbac.grant(role.name, p.name);
    });
  });
});

2. 基于路由的 RBAC

在实际应用中,我们经常需要根据路由判断当前用户是否有权限访问某些页面或 API,基于路由实现 RBAC 就可以方便地完成这个需求。

以 Express 框架为例,我们使用 express-rbac 包来实现基于路由的 RBAC。首先安装 express-rbac 包:

npm install express-rbac --save

声明一个路由数组,如下所示:

const routes = [
  {
    path: '/',
    method: 'GET',
    handler: (req, res, next) => { res.send('Home Page'); },
    permission: 'home:view' // Home 页面需要 home:view 权限
  },
  {
    path: '/about',
    method: 'GET',
    handler: (req, res, next) => { res.send('About Page'); },
    permission: 'about:view' // About 页面需要 about:view 权限
  },
  {
    path: '/admin',
    method: 'GET',
    handler: (req, res, next) => { res.send('Admin Page'); },
    permission: 'admin:view' // Admin 页面需要 adimin:view 权限
  }
];

然后在创建 Express 应用时,配置中间件来实现权限控制:

const express = require('express');
const RbacMiddleware = require('express-rbac');
const RBAC = require('node-rbac');

const rbac = new RBAC();

rbac.createRole('guest')
    .createPermission('home:view');

rbac.createRole('admin')
    .createPermission('home:view');

rbac.grant('guest', 'user:123');  
rbac.grant('admin', 'user:789');  

const app = express();

app.use(RbacMiddleware(rbac));

routes.forEach((route) => {
  app[route.method.toLowerCase()](route.path, (req, res, next) => {
    req.rbac.check(route.permission)
      ? route.handler(req, res, next)
      : res.status(401).send('Access Denied');
  });
});

最后,我们可以使用浏览器或命令行工具进行访问:

curl http://localhost/ # 返回 Home Page
curl http://localhost/about # 返回 About Page
curl http://localhost/admin # 返回 Access Denied

这些都是用户权限系数所影响的结果。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/600673e1fb81d47349e53d57


纠错
反馈