关键词

详解nodejs中express搭建权限管理系统

下面我为您详细讲解“详解nodejs中express搭建权限管理系统”的完整攻略。

一、前置准备

在开始搭建权限管理系统之前,我们需要先进行一些前置准备工作:

  • 熟悉 Nodejs 和 Express 框架的基本语法和使用方法。
  • 安装 MongoDB 数据库和 Mongoose 数据库模块。
  • 了解 session 和 cookie 的基本概念。

二、安装依赖

接下来,我们需要安装一些依赖,这些依赖包括 express、body-parser、cookie-parser、express-session、mongoose、morgan、bcryptjs、cors、jsonwebtoken 等多个模块,具体安装命令如下:

npm install express body-parser cookie-parser express-session mongoose morgan bcryptjs cors jsonwebtoken --save

三、搭建项目框架

接下来,我们可以开始搭建项目框架了。具体步骤如下:

  1. 创建项目目录:
mkdir permission
  1. 进入项目目录后,初始化项目:
npm init -y
  1. 创建主文件 index.js:
touch index.js
  1. 打开 index.js 文件,引入必要的模块:
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const mongoose = require('mongoose');
const morgan = require('morgan');
const bcrypt = require('bcryptjs');
const cors = require('cors');
const jwt = require('jsonwebtoken');

四、搭建数据库模型

在搭建权限管理系统之前,我们需要定义好数据库中的数据模型。在此示例中,我们定义了两个模型,一个是用户模型,另一个是角色模型。具体代码如下:

//users模型
const userSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true, // 唯一性限制
    required: true // 必填项
  },
  password: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  role: { // 关联角色模型
    type: mongoose.Schema.Types.ObjectId,
    ref: 'roles'
  }
});

//角色模型
const roleSchema = new mongoose.Schema({
  name: {
    type: String,
    unique: true,
    required: true
  },
  permissions: { // 权限集合
    type: Array,
    default: []
  }
});

五、搭建路由

在完成数据模型的定义之后,我们需要搭建路由来响应客户端请求。在此示例中,我们定义了以下几个路由:

  1. 用户注册路由
app.post('/api/users/register', async (req, res) => {
  const { username, password, email } = req.body;
  const hashPassword = await bcrypt.hash(password, 10);
  const role = await Role.findOne({ name: 'user' }); // 默认注册为普通用户
  const user = new User({ username, password: hashPassword, email, role: role._id });
  await user.save();
  res.send('注册成功');
});
  1. 用户登录路由
app.post('/api/users/login', async (req, res) => {
  const { username, password } = req.body;
  const user = await User.findOne({ username });
  if (!user) {
    return res.status(400).send({ message: '用户名或密码错误' }); // 用户不存在
  }
  const isValid = await bcrypt.compare(password, user.password);
  if (!isValid) {
    return res.status(400).send({ message: '用户名或密码错误' }); // 密码错误
  }
  const token = jwt.sign({ userId: user._id }, 'secretkey'); // 生成 token
  res.cookie('token', token, { httpOnly: true }); // 设置 cookie
  res.send('登录成功');
});
  1. 获取用户信息路由
app.get('/api/users/info', async (req, res) => {
  const token = req.cookies.token;
  try {
    const decoded = jwt.verify(token, 'secretkey'); // 验证 token
    const user = await User.findOne({ _id: decoded.userId }).populate('role');
    if (!user) {
      return res.status(401).send({ message: '用户未登录' });
    }
    res.send(user);
  } catch {
    return res.status(401).send({ message: '用户未登录' });
  }
});
  1. 获取角色列表路由
app.get('/api/roles', async (req, res) => {
  const roles = await Role.find(); // 获取角色列表
  res.send(roles);
});

六、搭建中间件

在进行权限管理时,我们需要使用中间件来对客户端请求进行鉴权验证。在此示例中,我们定义了以下中间件:

  1. 鉴权中间件
const authMiddleware = async (req, res, next) => {
  const token = req.cookies.token;
  try {
    const decoded = jwt.verify(token, 'secretkey'); // 验证 token
    const user = await User.findOne({ _id: decoded.userId }).populate('role');
    if (!user) {
      return res.status(401).send({ message: '用户未登录' });
    }
    req.user = user;
    next();
  } catch {
    return res.status(401).send({ message: '用户未登录' });
  }
};
  1. 权限验证中间件
const permissionMiddleware = (permissions) => async (req, res, next) => {
  const user = req.user;
  const role = await Role.findOne({ _id: user.role });
  const hasPermission = permissions.every(p => role.permissions.indexOf(p) > -1); // 判断用户是否拥有对应权限
  if (!hasPermission) {
    return res.status(403).send({ message: '无操作权限' });
  }
  next();
};

七、实现权限管理

在完成路由和中间件的搭建之后,我们可以开始进行权限管理了。在此示例中,我们定义了以下两种权限请求:

  1. user:update 权限

示例代码如下:

// 当某个用户想要更新自己的资料时,需要拥有 user:update 权限
app.put('/api/users', authMiddleware, permissionMiddleware(['user:update']), async (req, res) => {
  const { username, email } = req.body;
  const user = req.user;
  user.username = username;
  user.email = email;
  await user.save();
  res.send('更新成功');
});
  1. role:create 权限

示例代码如下:

// 当管理员需要创建新角色时,需要拥有 role:create 权限
app.post('/api/roles', authMiddleware, permissionMiddleware(['role:create']), async (req, res) => {
  const roleName = req.body.name;
  const role = new Role({ name: roleName });
  await role.save();
  res.send('创建成功');
});

至此,我们的权限管理系统已经搭建完毕。

八、示例说明

以下是两条示例说明:

  1. 用户注册

客户端请求:

fetch('/api/users/register', {
  method: 'post',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: 'lucy', password: '123456', email: 'lucy@gmail.com' })
}).then(res => {
  console.log(res.text());
});

服务端响应:

注册成功
  1. 获取角色列表

客户端请求:

fetch('/api/roles').then(res => {
  res.json().then(roles => {
    console.log(roles);
  });
});

服务端响应:

[
  { "_id": "6132fc256e86112f6ff9d2cc", "name": "user", "permissions": [] },
  { "_id": "6132fc356e86112f6ff9d2cd", "name": "admin", "permissions": ["user:update", "role:create"] }
]

以上就是详解 nodejs 中 express 搭建权限管理系统的完整攻略。

本文链接:http://task.lmcjl.com/news/14292.html

展开阅读全文