express+mySql实现用户注册、登录和身份认证
express+mySql实现用户注册、登录和身份认证
注册
注册时需要对用户密码进行加密入库,提高账户的安全性。用户登录时再将密码以相同的方式进行加密,再与数据库中存储的密码进行比对,相同则表示登录成功。
安装加密依赖包bcryptjs
cnpm install -S bcryptjs
在注册接口中添加加密功能
// 引入对密码进行加密的包
const bcryptjs = require("bcryptjs");
class User {register(req, res) {let { username, nick_name, password } = req.body;// 先查找注册的用户名是否在数据库中已存在const sql = "select * from sys_user where user_name=?";pool.query(sql, username, (err, results) => {if (err) return res.sendError(err);// 找到了要注册的用户名if (results.length >= 1) return res.sendError("当前用户名已被占用!");// 对密码进行加密,第二个参数可以提高密码的安全性为任意数字const password1 = bcryptjs.hashSync(password, 10);const SQl = `Insert into sys_user (user_name,password,nick_name) values('${username}', '${password1}', '${nick_name}')`pool.query(SQl, (err, data) => {if (err) return res.sendError(err);if (data.affectedRows !== 1) {res.sendError('用户注册失败"');} else {res.sendSuccess(data);}})})}
}
效果展示



登录
安装加密依赖包jsonwebtoken
jsonwebtokenuaokeyi生成用户登录需要的token信息。
cnpm install -S jsonwebtoken
增加全局token配置文件
在项目根目录的config文件夹下新增taken.js文件,并加入如下配置。
// 全局的配置文件
module.exports = {// 设置token加密和解密用到的密钥jwtSecretKey: 'qwertyuiop',// 设置token的有效期expiresIn: '10h',
}

在登录接口中返回taken信息
// 导入jsonwebtoken
const jwt = require("jsonwebtoken");
// 导入全局配置文件
const taken = require("../config/taken");
class User {login(req, res) {const { username, password } = req.body;// 先查找用户名是否在数据库中,定义sql语句const sql = "select * from sys_user where user_name=?";pool.query(sql, username, (err, results) => {if (err) return res.sendError(err);if (results.length !== 1) return res.sendError("当前用户不存在!");// 比较密码 compareSync(客户端的密码,数据库中存储的经过加密后的密码)会返回true或falseconst compareResult = bcryptjs.compareSync(password, results[0].password);if (!compareResult) {return res.sendError("用户密码错误,登录失败!");}// 密码比对正确,在服务端根据用户信息(用户密码需置空)生成token信息const user = { ...results[0], password: "" };// 对用户的信息进行加密,生成token字符串const tokenStr = jwt.sign(user, taken.jwtSecretKey, {expiresIn: taken.expiresIn,});// 调用res.send将token响应给客户端res.sendSuccess("Bearer " + tokenStr)})}
}
效果展示

配置系统白名单
白名单是指那些接口不需要提供token信息。
安装解析token的依赖包express-jwt
express-jwt 包需要使用和生成token时相同的密钥。
cnpm install -S express-jwt
修改app.js文件设置系统白名单
// 在路由之前配置解析token的中间件
const { expressjwt: jwt } = require("express-jwt")
// 解析token时需要token的密钥
const taken = require("./config/taken");
// 定义中间件,
// .unless指定哪些接口不需要进行token身份认证(过滤掉swagger页面和login接口)
app.use(jwt({ secret: taken.jwtSecretKey, algorithms: ["HS256"] }).unless({path: [/^\/api-docs/, '/user/login', '/user/register'],})
)
效果展示


在其他接口中通过token获取具体的用户信息
在接口中通过req.auth中获取:具体代码如下:
class mineSeam {getAll(req, res) {console.log(req.auth)}
}

app.js全部代码如下
// 引入express
const express = require("express");
const path = require('path');
const router = require('./routes/index.js');// 创建服务器的实例对象
const app = express();// 配置解析表单数据的中间件,内置中间件只能解析application/x-www-form-urlencoded格式的数据
app.use(express.urlencoded({ extended: false }));// 搭建静态文件服务
app.use(express.static(path.join(__dirname, 'public')));// 引入swagger配置项
const swaggerSpec = require('./config/swagger')
app.get('/swagger.json', function(req, res) {res.setHeader('Content-Type', 'application/json');res.send(swaggerSpec);
});/*** 在路由之前封装res.send()*/
app.use((req, res, next) => {// 定义一个输出的函数res.sendError = function (err) {res.send({code: 400,msg: err instanceof Error ? err.message : err})}// 定义一个输出的函数res.sendSuccess = function (data = null) {res.send({code: 200,msg: '成功',data})}next();
})// 在路由之前配置解析token的中间件
const { expressjwt: jwt } = require("express-jwt");
// 解析token需要token的密钥
const taken = require("./config/taken");
// 定义中间件,需要哪个密钥解析
// algorithms:设置jwt的算法
// .unless指定哪些接口不需要进行token身份认证
app.use(jwt({ secret: taken.jwtSecretKey, algorithms: ["HS256"] }).unless({path: [/^\/api-docs/, '/user/login', '/user/register'],})
)// 引入路由
router(app);// 引入校验规则的包,在定义错误级别的中间件时会用到
const joi = require('joi')
// 在所有路由下面调用错误级别的中间件
app.use((err, req, res, next) => {// 验证失败导致的错误if (err instanceof joi.ValidationError) return res.sendError(err);// 未知的错误res.sendError(err);next();
})// 启动服务器,3007为端口号,选择一个空闲的端口号
app.listen(3007, () => {console.log("Server running at http://127.0.0.1:3007");
})
参考链接
链接1
相关文章:
express+mySql实现用户注册、登录和身份认证
expressmySql实现用户注册、登录和身份认证 注册 注册时需要对用户密码进行加密入库,提高账户的安全性。用户登录时再将密码以相同的方式进行加密,再与数据库中存储的密码进行比对,相同则表示登录成功。 安装加密依赖包bcryptjs cnpm insta…...
【PyTorch】(二)加载数据集
文章目录 1. 创建数据集1.1. 直接继承Dataset类1.2. 使用TensorDataset类 2. 加载数据集3. 将数据转移到GPU 1. 创建数据集 主要是将数据集读入内存,并用Dataset类封装。 1.1. 直接继承Dataset类 必须要重写__getitem__方法,用于根据索引获得相应样本…...
如何提高3D建模技能?
无论是制作影视动画还是视频游戏,提高3D建模技能对于你的工作都至关重要的。那么如何能创建出精美的3D模型呢?本文给大家一些3D建模技能方面的建议。 3D建模通过专门的软件完成,涉及制作三维对象。这项技能在视频游戏开发、建筑、动画和产品…...
【前端开发】Next.js与Nest.js之间的差异2023
在快节奏的网络开发领域,JavaScript已成为构建可靠且引人入胜的在线应用程序的标准语言。然而,随着对适应性强、高效的在线服务的需求不断增加,开发人员通常不得不从广泛的库和框架中进行选择,以满足其项目的要求。Next.js和Nest.…...
【CAN通信】CanIf模块详细介绍
目录 1.内容简介 2.CanIf详细设计 2.1 CanIf功能简介 2.2 一些关键概念 2.3依赖的上下层模块 2.4 功能详细设计 2.4.1 Hardware object handles 2.4.2 Static L-PDUs 2.4.3 Dynamic L-PDUs 2.4.4 Dynamic Transmit L-PDUs 2.4.5 Dynamic receive L-PDUs 2.4.6Physi…...
PS最新磨皮软件Portraiture4.1.2
Portraiture是一款好用的PS磨皮滤镜插件,拥有磨皮美白的功能,操作也很简单,一键点击即可实现美白效果,软件还保留了人物的皮肤质感让照片看起来更加真实。portraiture体积小巧,不会占用过多的电脑内存哦。 内置了多种…...
旋转框(obb)目标检测计算iou的方法
首先先定义一组多边形,这里的数据来自前后帧的检测结果 pre [[[860.0, 374.0], [823.38, 435.23], [716.38, 371.23], [753.0, 310.0]],[[829.0, 465.0], [826.22, 544.01], [684.0, 539.0], [686.78, 459.99]],[[885.72, 574.95], [891.0, 648.0], [725.0, 660.0]…...
render函数举例
在这段代码中,renderButton是一个对象吗 还有render为什么不能写成render() {} 代码原文链接 <template><div><renderButton /></div> </template><script setup> import { h, ref } from "vue"; const renderButt…...
微信小程序文件预览和下载-文件系统
文件预览和下载 在下载之前,我们得先调用接口获取文件下载的url 然后通过wx.downloadFile将下载文件资源到本地 wx.downloadFile({url: res.data.url,success: function (res) {console.log(数据,res);} })tempFilePath就是临时临时文件路径。 通过wx.openDocume…...
图解Redis适用场景
Redis以其速度而闻名。 1 业务数据缓存 1.1 通用数据缓存 string,int,list,map。Redis 最常见的用例是缓存对象以加速 Web 应用程序。 此用例中,Redis 将频繁请求的数据存储在内存。允许 Web 服务器快速返回频繁访问的数据。这…...
掌握Python BentoML:构建、部署和管理机器学习模型
更多资料获取 📚 个人网站:ipengtao.com BentoML是一个开源的Python框架,旨在简化机器学习模型的打包、部署和管理。本文将深入介绍BentoML的功能和用法,提供详细的示例代码和解释,帮助你更好地理解和应用这个强大的工…...
西南科技大学模拟电子技术实验二(二极管特性测试及其应用电路)预习报告
目录 一、计算/设计过程 二、画出并填写实验指导书上的预表 三、画出并填写实验指导书上的虚表 四、粘贴原理仿真、工程仿真截图 一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入…...
熟悉SVN基本操作-(SVN相关介绍使用以及冲突解决)
一、SVN相关介绍 1、SVN是什么? 代码版本管理工具它能记住你每次的修改查看所有的修改记录恢复到任何历史版本恢复已经删除的文件 2、SVN跟Git比,有什么优势 使用简单,上手快目录级权限控制,企业安全必备子目录checkout,减少…...
代码随想录二刷 |字符串 |反转字符串II
代码随想录二刷 |字符串 |反转字符串II 题目描述解题思路 & 代码实现 题目描述 541.反转字符串II 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。 如果…...
哪吒汽车拔头筹,造车新势力首家泰国工厂投产
中国造车新势力首家泰国工厂投产!11月30日,哪吒汽车位于泰国的首家海外工厂——泰国生态智慧工厂正式投产下线新车,哪吒汽车联合创始人兼CEO张勇、哪吒汽车泰国合作伙伴BGAC公司首席执行官万查曾颂翁蓬素等出席仪式。首辆“泰国制造”的哪吒汽…...
Redis String类型
String 类型是 Redis 最基本的数据类型,String 类型在 Redis 内部使用动态长度数组实现,Redis 在存储数据时会根据数据的大小动态地调整数组的长度。Redis 中字符串类型的值最大可以达到 512 MB。 关于字符串需要特别注意∶ 首先,Redis 中所…...
lxd提权
lxd/lxc提权 漏洞介绍 lxd是一个root进程,它可以负责执行任意用户的lxd,unix套接字写入访问操作。而且在一些情况下,lxd不会调用它的用户权限进行检查和匹配 原理可以理解为用用户创建一个容器,再用容器挂载宿主机磁盘…...
Ubuntu+Tesla V100环境配置
系统基本信息 nvidia-smi’ nvidia-smi 470.182.03 driver version:470.182.03 cuda version: 11.4 查看系统体系结构 uname -aUTC 2023 x86_64 x86_64 x86_64 GNU/Linux 下载miniconda https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/?CM&OA https://mi…...
leetcode:用栈实现队列(先进先出)
题目描述 题目链接:232. 用栈实现队列 - 力扣(LeetCode) 题目分析 我们先把之前写的数组栈的实现代码搬过来 用栈实现队列最主要的是实现队列先进先出的特点,而栈的特点是后进先出,那么我们可以用两个栈来实现&…...
<JavaEE> 什么是进程控制块(PCB Process Control Block)?
目录 一、进程控制块的概念 二、进程控制块的重要属性 2.1 唯一身份标识(PID) 2.2 内存指针 2.3 文件描述符表 2.4 状态 2.5 优先级 2.6 记账信息 2.7 上下文 一、进程控制块的概念 进程控制块(Process Control Block, PCBÿ…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
