前言
在现代开发中,权限控制是不可或缺的一部分,它能够有效地保护系统和用户的安全。而在运用权限控制时,基于角色的访问控制(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
的数据库,并创建 roles
和 permissions
集合,如下所示:
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