详解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 搭建权限管理系统的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解nodejs中express搭建权限管理系统 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • 在Linux系统中将Redmine和SVN整合入Nginx的方法

    将Redmine和SVN整合入Nginx的方法,可以通过以下步骤完成: 1. 安装和配置Redmine 1.1 安装Ruby和Rails 首先需要安装Ruby和Rails。在命令行输入以下命令: sudo apt-get update sudo apt-get install ruby rails 1.2 下载和解压Redmine 到Redmine官网下载安…

    人工智能概览 2023年5月25日
    00
  • 完美处理python与anaconda环境变量的冲突问题

    针对这个问题,我会提供一份完整的攻略。 1. 什么是环境变量? 在深入讲解这个问题之前,我们首先需要了解一下什么是“环境变量”。环境变量可以理解为是全局变量,可以在不同的程序中被调用。在操作系统中,每个进程都有自己的一组环境变量。 在Windows系统中,我们可以通过“控制台 > 系统和安全 > 系统 > 高级系统设置 > 环境变量”…

    人工智能概览 2023年5月25日
    00
  • c# 实现语音合成

    C# 实现语音合成 语音合成是将文本转化为声音的技术,能够为用户带来良好的使用体验。下面是详细的“C# 实现语音合成”的攻略,包含两条示例说明。 准备工作 在开始编写代码前,需要做好以下准备工作: 下载安装 Microsoft Speech Platform SDK。 下载安装 Speech Platform Runtime。 实现步骤 1. 引入命名空间 …

    人工智能概论 2023年5月25日
    00
  • Visual Studio 2015和 .NET Core安装教程

    Visual Studio 2015和 .NET Core安装教程 安装Visual Studio 2015 首先,从Microsoft官网(https://www.visualstudio.com/downloads/)下载Visual Studio 2015安装包。 运行下载的安装包,选择 “Custom” 选项进行安装。在该选项卡中,选择要安装的组件(…

    人工智能概览 2023年5月25日
    00
  • OpenCV实现车牌定位(C++)

    OpenCV实现车牌定位(C++) 背景介绍 车牌定位是智能交通系统、物流系统等应用中的一个重要的识别环节。本文将介绍基于OpenCV库的车牌定位方法。 环境准备 在运行本文代码前,请确保已经安装以下环境:- OpenCV库- C++编译器 方法介绍 车牌定位主要有以下几个步骤: 1. 车辆图像预处理 车辆图像一般需要经过预处理才能进行车牌定位。预处理包括:…

    人工智能概览 2023年5月25日
    00
  • Python OpenCV视频截取并保存实现代码

    下面针对Python OpenCV视频截取并保存实现代码的完整攻略进行详细讲解。 1. 导入OpenCV库 在Python中运用OpenCV库实现视频截取需要先导入相关库。使用以下代码实现: import cv2 2. 打开视频文件 使用OpenCV的VideoCapture函数打开视频文件,你可以将视频文件的地址作为参数向函数传递。 cap = cv2.V…

    人工智能概论 2023年5月24日
    00
  • pytorch教程实现mnist手写数字识别代码示例

    下面是“pytorch教程实现mnist手写数字识别代码示例”的攻略。 概述 在这个教程中,我们将使用PyTorch框架来实现一个手写数字识别模型,即利用深度学习技术识别“0”到“9”共10个数字。我们将使用一个称为MNIST的数据集,它包含了大量由手写数字扫描所得的数字图像。具体而言,我们将建立一个由2个卷积层、2个全连接层和一个输出层组成的神经网络模型,…

    人工智能概论 2023年5月25日
    00
  • Python如何获取Win7,Win10系统缩放大小

    获取Win7,Win10系统缩放大小可以使用Python的win32api模块,下面是完整攻略: 安装win32api模块 首先需要安装pywin32模块,可以通过pip安装,命令如下: pip install pywin32 如果是anaconda环境,则可以使用以下命令安装: conda install pywin32 使用win32api获取缩放大小 …

    人工智能概览 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部