【综合项目】api系统——基于Node.js、express、mysql等技术

目录

0 前言 

1 初始化

2 注册登录 

2.1 注册

2.1.1 功能:密码加密(2.3.3)

2.1.1.1 操作 

2.1.1.2 bcryptjs详解

2.1.2 插入新用户(2.3.4) 

 2.1.3 优化:表单数据验证(2.5)

2.1.3.1 过时代码修正

2.1.3.2 关键操作

2.2 登录 

2.2.1 判断密码是否正确(2.6.3)

2.2.2 生成 JWT 的 Token 字符串的注意点(2.6.4)

3 个人中心

3.1 更新用户基本信息

3.1.1 验证表单数据(3.2.2)

3.2 重置密码

3.2.1 验证表单数据(3.3.2)

3.3 更新头像

3.3.1 验证表单数据(3.4.2)

4 文章分类管理

4.1 根据Id更新文章分类数据

4.1.1 查询分类名称与别名是否被占用(4.5.4)

5 文章管理

5.1 发布新文章

5.1.1 使用 multer 解析表单数据(5.2.3)

 5.1.2 验证表单数据(5.2.4)

5.1.3 新建数据对象(5.2.5)


0 前言 

本章仅记录部分功能代码(以前文章中未涉及的新内容)以及所遇到的问题

详细内容见  项目首页 - api系统 - GitCode  中的指导文档

❗❗❗最终完整代码也会上传至GitCode中,收藏方便查找

注:部分标题后面跟了原文档中的序号,方便查看


1 初始化

此部分暂无内容


2 注册登录 

2.1 注册

2.1.1 功能:密码加密(2.3.3)

2.1.1.1 操作 

使用 bcryptjs 对用户密码进行加密 

安装指定版本的 bcryptjs :

npm i bcryptjs@2.4.3

导入 bcryptjs :

const bcrypt = require('bcryptjs')

在注册用户的处理函数中,确认用户名可用之后,调用 bcrypt.hashSync(明文密码, 随机盐的长度) 方法,对用户的密码进行加密处理:

// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
userinfo.password = bcrypt.hashSync(userinfo.password, 10)

2.1.1.2 bcryptjs详解

bcrypt.hashSync 是 `bcrypt` 库中用于同步生成哈希值的函数,在 Node.js 中经常使用该库来对密码等敏感信息进行哈希处理。以下详细介绍 bcrypt.hashSync 函数的参数:

函数

bcrypt.hashSync(data, saltOrRounds);

参数说明

1. data
类型:string
描述:需要进行哈希处理的数据,通常是用户的密码。这是一个必需的参数,代表你要加密的原始文本。

2. saltOrRounds
类型:string 或 number
描述:该参数可以是一个盐值(string 类型),也可以是生成盐的轮数(number 类型)。

当 saltOrRounds 为 number 类型时
它代表生成盐的轮数,也称为成本因子(cost factor)。这个值越大,生成盐和哈希值所花费的时间就越长,安全性也相对更高。推荐的值通常在 10 - 12 之间。
bcrypt 会根据这个轮数自动生成一个随机的盐值,然后使用这个盐值对 data 进行哈希处理。

当 saltOrRounds 为 string 类型时
它代表一个预先定义好的盐值。使用自定义盐值时,每次使用相同的盐和数据进行哈希处理,会得到相同的哈希结果。
一般情况下,不建议手动指定盐值,因为 bcrypt 自动生成的随机盐值可以更好地保证安全性。

返回值

bcrypt.hashSync 函数会返回一个包含盐值和哈希值的字符串,这个字符串可以安全地存储在数据库中,用于后续的密码验证。


2.1.2 插入新用户(2.3.4) 

判断插入是否成功

if (results.affectedRows !== 1) {
return res.send({ status: 1, message: '注册用户失败,请稍后再试!' })
}

即判断影响数据行数是否为1


 2.1.3 优化:表单数据验证(2.5)

2.1.3.1 过时代码修正

const joi = require('@hapi/joi') 的写法现在已经失效,

应该这样导入:const joi = require('joi')


2.1.3.2 关键操作

安装 @hapi/joi 包,为表单中携带的每个数据项,定义验证规则:

npm install @hapi/joi@17.1.0

安装 @escook/express-joi 中间件,来实现自动对表单数据进行验证的功能:

 npm i @escook/express-joi

常用验证规则:

除此之外,本文下方的验证表单数据中还包含一些其他常用规则

 /*** string() 值必须是字符串* alphanum() 值只能是包含 a-zA-Z0-9 的字符串* min(length) 最小长度* max(length) 最大长度* required() 值是必填项,不能为 undefined* pattern(正则表达式) 值必须符合正则表达式的规则*/

注意:一定要先指定一种数据类型string()或者其他(包括any()),然后才能执行后续操作


导出规则

// 注册和登录表单的验证规则对象
exports.reg_login_schema = {
// 表示需要对 req.body 中的数据进行验证body: {username,password,},}

使用规则

 // 1. 导入验证表单数据的中间件
const expressJoi = require('@escook/express-joi')// 2. 导入需要的验证规则对象
const { reg_login_schema } = require('../schema/user')//...router.post('/reguser', expressJoi(reg_login_schema), userHandler.regUser)

2.2 登录 

2.2.1 判断密码是否正确(2.6.3)

使用加密密码的包bcrypt

返回值是布尔值(true 一致、false 不一致)

bcrypt.compareSync(用户提交的密码, 数据库中的密码)

 示例:

// 拿着用户输入的密码,和数据库中存储的密码进行对比
const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)
// 如果对比的结果等于 false, 则证明用户输入的密码错误
if (!compareResult) {return res.cc('登录失败!')
}
// TODO:登录成功,生成 Token 字符串

2.2.2 生成 JWT 的 Token 字符串的注意点(2.6.4)

核心注意点:在生成 Token 字符串的时候,一定要剔除 密码 和 头像 的值 

通过 ES6 的高级语法,快速剔除 密码 和 头像 的值: 

// 剔除完毕之后,user 中只保留了用户的 id, username, nickname, email 这四个属性的值
const user = { ...results[0], password: '', user_pic: '' }

3 个人中心

3.1 更新用户基本信息

3.1.1 验证表单数据(3.2.2)

记录新属性

 const id = joi.number().integer().min(1).required()const nickname = joi.string().required()const email = joi.string().email().required()

integer() 方法用于验证一个值是否为整数 


3.2 重置密码

3.2.1 验证表单数据(3.3.2)

body: {// 使用 password 这个规则,验证 req.body.oldPwd 的值oldPwd: password,newPwd: joi.not(joi.ref('oldPwd')).concat(password),},

  使用 joi.not(joi.ref('oldPwd')).concat(password) 规则,验证 req.body.newPwd 的值

  解读:

    1. joi.ref('oldPwd') 表示 newPwd 的值必须和 oldPwd 的值保持一致

    2. joi.not(joi.ref('oldPwd')) 表示 newPwd 的值不能等于 oldPwd 的值

    3. .concat() 用于合并 joi.not(joi.ref('oldPwd')) 和 password 这两条验证规则


3.3 更新头像

3.3.1 验证表单数据(3.4.2)

// dataUri() 指的是如下格式的字符串数据:
// data:image/png;base64,VE9PTUFOWVNFQ1JFVFM=const avatar = joi.string().dataUri().required()

dataUrl() 方法用于验证一个字符串是否符合数据 URL 的格式


4 文章分类管理

4.1 根据Id更新文章分类数据

4.1.1 查询分类名称与别名是否被占用(4.5.4)

SELECT * FROM ev_article_cate WHERE Id <> ? AND (name = ? or alias = ?)

注意:已有数据的情况下进行更新内容,需要排除当前数据的内容,否做无法做到部分内容修改!


5 文章管理

5.1 发布新文章

5.1.1 使用 multer 解析表单数据(5.2.3)

URL-encoded:适用于传输简单的文本数据,例如表单中的文本字段

multipart/form-data:适用于上传文件或包含二进制数据的表单

注意:使用 express.urlencoded() 中间件无法解析 multipart/form-data 格式的请求体数据

当前项目,推荐使用 multer 来解析 multipart/form-data 格式的表单数据

安装:

 npm i multer@1.4.2

创建与使用:

// 导入解析 formdata 格式表单数据的包
const multer = require('multer')// 导入处理路径的核心模块
const path = require('path')
// 创建 multer 的实例对象,通过 dest 属性指定文件的存放路径
const upload = multer({ dest: path.join(__dirname, '../uploads') })// 发布新文章的路由
// upload.single() 是一个局部生效的中间件,用来解析 FormData 格式的表单数据
// 将文件类型的数据,解析并挂载到 req.file 属性中
// 将文本类型的数据,解析并挂载到 req.body 属性中
router.post('/add', upload.single('cover_img'), article_handler.addArticle)

之后文本类型的数据,即字段会通过joi来进行规则验证,但是文件类型的数据不行,得额外用if判断 


 5.1.2 验证表单数据(5.2.4)

注意:先后顺序一定不能变,因为multer会将其他字段挂载到req.body上,如果在joi之后,会导致部分字段不会被joi检测

// 导入验证数据的中间件
const expressJoi = require('@escook/express-joi')// 导入文章的验证模块
const { add_article_schema } = require('../schema/article')// 发布新文章的路由
// 注意:在当前的路由中,先后使用了两个中间件:
//       先使用 multer 解析表单数据
//       再使用 expressJoi 对解析的表单数据进行验证
router.post('/add', upload.single('cover_img'), expressJoi(add_article_schema), 
article_handler.addArticle)

验证文件类型:

 // 发布新文章的处理函数
exports.addArticle = (req, res) => {// 手动判断是否上传了文章封面if (!req.file || req.file.fieldname !== 'cover_img') return res.cc('文章封面是必选
参数!')// TODO:表单数据合法,继续后面的处理流程...})

5.1.3 新建数据对象(5.2.5)

 const articleInfo = {// 标题、内容、状态、所属的分类Id...req.body,// 文章封面在服务器端的存放路径cover_img: path.join('/uploads', req.file.filename),// 文章发布时间pub_date: new Date(),// 文章作者的Idauthor_id: req.user.id,}

断更...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72174.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tableau之标靶图、甘特图和瀑布图

一、标靶图 概念 标靶图&#xff08;Bullet Chart&#xff09;是一种用于显示数据与目标之间关系的可视化图表&#xff0c;常用于业务和管理报告中。其设计旨在用来比较实际值与目标值&#xff0c;同时展示额外的上下文信息&#xff08;如趋势&#xff09;。 作用 可视化目标…

Linux下的网络通信编程

在不同主机之间&#xff0c;进行进程间的通信。 1解决主机之间硬件的互通 2.解决主机之间软件的互通. 3.IP地址&#xff1a;来区分不同的主机&#xff08;软件地址&#xff09; 4.MAC地址&#xff1a;硬件地址 5.端口号&#xff1a;区分同一主机上的不同应用进程 网络协议…

网络七层模型—OSI参考模型详解

网络七层模型&#xff1a;OSI参考模型详解 引言 在网络通信的世界中&#xff0c;OSI&#xff08;Open Systems Interconnection&#xff09;参考模型是一个基础且核心的概念。它由国际标准化组织&#xff08;ISO&#xff09;于1984年提出&#xff0c;旨在为不同厂商的设备和应…

530 Login fail. A secure connection is requiered(such as ssl)-java发送QQ邮箱(简单配置)

由于cs的csdN许多文章关于这方面的都是vip文章&#xff0c;而本文是免费的&#xff0c;希望广大网友觉得有帮助的可以多点赞和关注&#xff01; QQ邮箱授权码到这里去开启 授权码是16位的字母&#xff0c;填入下面的mail.setting里面的pass里面 # 邮件服务器的SMTP地址 host…

Sqlserver安全篇之_TLS的证书概念

证书的理解 参考Sqlserver的官方文档https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/certificate-overview?viewsql-server-ver16 TLS(Transport Layer Security)传输层安全和SSL(Secure Sockets Layer)安全套接字层协议位于应用程序协议层和TCP/…

【SQL】掌握SQL查询技巧:数据分组与排序

目录 1. GROUP BY 1.1 定义与用途1.2 示例说明1.3 注意事项1.4 可视化示例 2. ORDER BY 2.1 定义与用途2.2 升序说明&#xff08;默认&#xff09;2.3 降序排序2.4 多列排序2.5 可视化示例 3. GROUP BY 与 ORDER BY 的结合使用4. 可视化示例总结 在数据库管理中&#xff0c;S…

SOME/IP-SD -- 协议英文原文讲解6

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.3.1 E…

NameError: name ‘libpaddle‘ is not defined

问题场景&#xff1a; Error: Can not import paddle core while this file exists: C:\Users\Admin\AppData\Roaming\Python\Python38\site-packages\paddle\fluid\libpaddle.pyd Traceback (most recent call last): File "C:\Users\Admin\AppData\Roaming\Python\Pyth…

青少年编程与数学 02-010 C++程序设计基础 11课题、程序结构

青少年编程与数学 02-010 C程序设计基础 11课题、程序结构 一、C程序结构二、main函数1. main 函数的基本形式1.1 无参数形式1.2 带参数形式 2. 参数解释3. 示例3.1 无参数形式3.2 带参数形式 4. 编译和运行4.1 编译4.2 运行 5. main 函数的返回值6. 总结 三、预处理指令1. #in…

【Linux】learning notes(3)make、copy、move、remove

文章目录 1、mkdir &#xff08;make directory&#xff09;2、rmdir &#xff08;remove directory&#xff09;3、rm&#xff08;remove&#xff09;4、>5、touch 新建文件6、mv&#xff08;move&#xff09;7、cp&#xff08;copy&#xff09; 1、mkdir &#xff08;make…

智能AI替代专家系统(ES)、决策支持系统(DSS)?

文章目录 前言一、专家系统&#xff08;ES&#xff09;是什么&#xff1f;二、决策支持系统&#xff08;DSS&#xff09;是什么&#xff1f;1.决策支持系统定义2.决策系统的功能与特点3.决策支持系统的组成 三、专家系统&#xff08;ES&#xff09;与决策支持系统&#xff08;D…

实现Python+Django+Transformers库中的BertTokenizer和BertModel来进行BERT预训练,并将其应用于商品推荐功能

一、环境安装准备 #git拉取 bert-base-chinese 文件#创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django5.1#安装 pymysql settings.py 里面需要 # 强制…

Qt Creator + CMake 构建教程

此教程基于: Qt 6.7.4Qt Creator 15.0.1CMake 3.26.4 Qt 6 以下的版本使用 CMake 构建可能会存在一些问题. 目录 新建窗体工程更新翻译添加资源软件部署(Deploy) 此教程描述了如何一步步在 Qt Creator 中使用 CMake 构建应用程序工程. 涉及 新建窗体工程, 更新翻译, 添加资源, …

5个GitHub热点开源项目!!

1.自托管 Moonlight 游戏串流服务&#xff1a;Sunshine 主语言&#xff1a;C&#xff0c;Star&#xff1a;14.4k&#xff0c;周增长&#xff1a;500 这是一个自托管的 Moonlight 游戏串流服务器端项目&#xff0c;支持所有 Moonlight 客户端。用户可以在自己电脑上搭建一个游戏…

【Mark】记录用宝塔+Nginx+worldpress+域名遇到的跨域,301,127.0.0.1,CSS加载失败问题

背景 想要用宝塔搭建worldpress&#xff0c;然后用域名直接转https&#xff0c;隐藏掉ipport。 结果被折磨了1天&#xff0c;一直在死活在301&#xff0c;127.0.0.1打转 还有css加载不了的情况 因为worldpress很多是301重定向的&#xff0c;所以改到最后我都不知道改了什么&am…

认知动力学视角下的生命优化系统:多模态机器学习框架的哲学重构

认知动力学视角下的生命优化系统&#xff1a;多模态机器学习框架的哲学重构 一、信息熵与生命系统的耗散结构 在热力学第二定律框架下&#xff0c;生命系统可视为负熵流的耗散结构&#xff1a; d S d i S d e S dS d_iS d_eS dSdi​Sde​S 其中 d i S d_iS di​S为内部熵…

考虑复杂遭遇场景下的COLREG,基于模型预测人工势场的船舶运动规划方法附Matlab代码

考虑复杂遭遇场景下的COLREG&#xff0c;基于模型预测人工势场的船舶运动规划方法附Matlab代码 一、引言 1.1、研究背景和意义 随着全球航运业的迅猛发展&#xff0c;船舶交通密度不断增大&#xff0c;海上交通事故频发&#xff0c;严重威胁到海上航行的安全。国际海上避碰规…

基于Kerberos认证对接华为云Elasticsearch

可以通过华为官方提供的Elasticsearch Java客户端&#xff08;基于Elasticsearch官方版本改造&#xff09;&#xff0c;实现基于Kerberos认证访问和操作华为云Elasticsearch&#xff1b;亦可以使用更加通用的开源Elasticsearch Java客户端bboss&#xff0c;实现基于Kerberos认证…

【湖北省计算机信息系统集成协会主办,多高校支持 | ACM出版,EI检索,往届已见刊检索】第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)

第二届边缘计算与并行、分布式计算国际学术会议&#xff08;ECPDC 2025&#xff09;将于2025年4月11日至13日在中国武汉盛大召开。本次会议旨在为边缘计算、并行计算及分布式计算领域的研究人员、学者和行业专家提供一个高水平的学术交流平台。 随着物联网、云计算和大数据技术…

CSS—背景属性与盒子模型(border、padding、margin)

目录 一.背景属性 二.盒子模型 1.边框border a. 圆角属性border-radius b. 图像属性border-image 2. 内边距padding 3. 外边距margin 3. 宽度width与高度height 一.背景属性 浏览器背景图默认是平铺效果&#xff08;复制图片直至填满设置的区域大小&#xff09; 背景…