当前位置: 首页 > news >正文

【Node.js】项目开发实战(中)

开发用户的注册和登录接口

          • 步骤1,打开MySQL Workbench,打开自己的数据库进入
          • 创建用户信息表
          • 新建 ev_users表
          • 安装并配置mysql模块
          • 安装mysql模块
          • 新建db文件夹下index.js,导入并配置mysql模块
          • 安装bcryptjs对密码进行加密处理
          • 新建/router_handler/user.js中,导入并使用bcrypt.js
      • router_handlerr/user.js用户模块里,书写注册的处理函数
      • 优化res.send()代码
      • 优化表单数据验证
          • 创建schema文件夹,新建user.js
      • 优化后的注册处理函数
      • 开发登录接口
          • 生成JWT的token字符串
          • 配置解析JWT的token字符串的中间件

步骤1,打开MySQL Workbench,打开自己的数据库进入
创建用户信息表
新建 ev_users表
  • id要加AI,设置成自增
    在这里插入图片描述
    在这里插入图片描述
安装并配置mysql模块
安装mysql模块
npm i mysql2
新建db文件夹下index.js,导入并配置mysql模块
// 1.导入mysql2模块
const mysql = require('mysql2')
// 2,建立与MySQL数据库的连接
const db = mysql.createPool({host: "127.0.0.1", //数据库的IP地址user: "root", //登录数据库的账号password: "lusheng123", //登录数据库的密码database: "my_db_01", //指定要操作哪个数据库
})
//3.检测mysql模块是否正常工作 SELECT 1 无作用,只是测试
db.query('SELECT 1',(err, results) => {//err为报错信息if (err) return console.log(err)//res是成功的消息console.log(results) 
}) 
module.exports = db
安装bcryptjs对密码进行加密处理
  • 安装 npm i bcryptjs@2.4.3
  • 优点:加密之后的密码,无法被逆向破解
  • 同一明文密码多次加密,得到到加密效果结果各不相同,保证了安全性
  • 目的,在数据库查看的时候,查看的是加密的密码
新建/router_handler/user.js中,导入并使用bcrypt.js
// 导入密码加密模块
const bcypt = require("bcryptjs")
// 加密用户密码,调用bcypt.hashSync(明文密码,随机盐的长度)方法
userinfo.password=bcypt.hashSync(userinfo.password,10)

router_handlerr/user.js用户模块里,书写注册的处理函数

  • 注意,sql语句要写对,
// 导入数据库操作模块
const db = require("../db/index")
// 导入密码加密模块
const bcypt = require("bcryptjs")
// 注册新用户
exports.reguser = (req, res) => {// 获取客户端提交到服务器的信息,进行校验const userinfo = req.bodyif (!userinfo.username || !userinfo.password) return res.send({status: 0, message: "用户名和密码不合法"})//定义SQL语句,查询用户名是否被占用const sqlStr = "select * from ev_users where username=?"db.query(sqlStr, userinfo.username, (err, result) => {if (err) return res.send({status: 0,message: err.message })// 判断用户名是否被占用if (result.length > 0) return res.send({status: 0, message: "用户名被占用,请更换用户名" })// 加密用户密码,调用bcypt.hashSync(明文密码,随机盐的长度)方法userinfo.password=bcypt.hashSync(userinfo.password,10)// 插入新用户const sql="insert into ev_users set ?"db.query(sql,{username:userinfo.username,password:userinfo.password},(err,results)=>{// 判断是否成功if(err)return res.send({status: 0,message: err.message })// 判断影响行数是否为1if(results.affectedRows!==1)return res.send({status:1,message:"注册用户失败"})return res.send({status: 1,message: "注册成功"})})})
}

优化res.send()代码

  • 在app.js文件里面
  • 注意:封装在路由之前
//响应数据的中间件,上游挂载,下游共享
app.use((req, res, next) => {// status=0是失败,status=1是成功,默认为0res.cc = (err, status = 0) => {res.send({status,// 判断err是错误对象还是字符串message: err instanceof Error ? err.message : err})}next()
})

优化表单数据验证

  • 前端验证为辅,后端验证为主
  • 后端是验证数据合法性验证的最后一个关口
  • 为提高效率,使用第三方库

安装npm i joi包,依赖

  • 定义每条数据的验证规则

安装npm i @escook/express-joi包,

  • 实现自动对表单数据进行验证的功能
创建schema文件夹,新建user.js
  • 存放定义的规则
// 导入joi,定义表单规则
const joi=require("joi")
// 导入express-joi中间件,表单验证模块
const expressJoi=require("@escook/express-joi")const userSchema ={// 校验req.body的数据body:{// 字符串,还必须字符和数字的组合,最小三位,最大12位,必传username:joi.string().alphanum().min(3).max(12).required(),// pattern指定正则表达式password:joi.string().pattern(/"[\s][6,15]$/),//当前规则和paddword规则保持一致repassword:joi.ref('password')},// 校验req.query的数据query:{},// 校验req.params的数据params:{}
}
// 暴露注册的表单验证规则
exports.userSchema=userSchema
  • 在router/user.js中,导入验证表单数据的中间件
//存放每个路由的对应关系
// 导入express
const express = require('express')// 创建路由对象
const router = express.Router()// 导入用户处理函数模块
const userhandler=require('../router_handler/user')// 1.导入验证表单数据的中间件
const expressJoi=require("@escook/express-joi")
// 2.导入需要验证的验证规则对象
const {userSchema}=require('../schema/user')// 3.采用局部中间件方式校·验,校验通过,会把请求转给后面的路由处理函数,校验不通过,终止后续代码的执行,并抛出一个全局的Error错误,进入全局错误中间件中进行处理
// 注册新用户
router.post('/reguser',expressJoi(userSchema),userhandler.reguser)// 登录
router.post('/login', userhandler.login)// 将路由对象共享出去
module.exports = router
  • 在app.js中,捕获表单验证的全局错误
  • 注意:写在路由之后!
//全局错误中间件,捕获表单验证失败的报错
app.use((err, req, res, next) => {if (err instanceof joi.ValidationError) return res.cc(err)res.cc(err)next()
})

优化后的注册处理函数

// 导入数据库操作模块
const db = require("../db/index")
// 导入密码加密模块
const bcypt = require("bcryptjs")
// 注册新用户处理函数
exports.reguser = (req, res) => {// 获取客户端提交到服务器的信息,进行校验const userinfo = req.bodyif (!userinfo.username || !userinfo.password) return res.cc("用户名和密码不合法")//定义SQL语句,查询用户名是否被占用const sqlStr = "select * from ev_users where username=?"db.query(sqlStr, userinfo.username, (err, result) => {if (result.length > 0) return  res.cc("用户名被占用,请更换用户名")// 加密用户密码,调用bcypt.hashSync(明文密码,随机盐的长度)方法userinfo.password=bcypt.hashSync(userinfo.password,10)// 插入新用户const sql="insert into ev_users set ?"db.query(sql,{username:userinfo.username,password:userinfo.password},(err,results)=>{// 判断是否成功if(err)return res.cc(err)// 判断影响行数是否为1if(results.affectedRows!==1)return res.cc("注册用户失败")return res.cc("注册成功",1)})})
}

开发登录接口

生成JWT的token字符串
  • 安装 npm i jsonwebtoken@8.5.1
  • 定义配置文件的秘钥和token有效期
//新建config.js
module.exports={//定义加密解密token的秘钥,随便写jwtSecretKey:'mimakey',// this.token有效期expiresIn:'10h'
}
  • 处理函数中也就是,router_header/user.js文件下引用导入
// 导入JWTtoken模块
const JWT = require("jsonwebtoken")
const config = require("../config")
  • 生成Jwt的token字符串的登录处理函数
// 导入数据库操作模块
const db = require("../db/index")
// 导入密码加密模块
const bcypt = require("bcryptjs")
// 导入JWTtoken模块
const JWT = require("jsonwebtoken")
const config = require("../config")
// 登录
exports.login = (req, res) => {const userinfo = req.bodyconst sql ='select * from ev_users where username=?'db.query(sql,userinfo.username,(err,results)=>{if(err) return res.cc(err);// 执行成功,但查询到的数据不等于1if(results.length!==1){return res.cc('登录失败')}// 验证密码是否和数据库的相同const reppassword= bcypt.compareSync(userinfo.password,results[0].password)if(!reppassword){return res.cc('登录失败,密码不一致')}// 登录成功,生成JWT的token字符串// 通过es6语法,剔除密码和头像const user ={...results[0],password:"",user_pic:""}// 对用户信息进行加密,生成token字符串,参数一是加密对象,参数2是加密秘钥,参数三是token有效期const tokenstr =JWT.sign(user,config.jwtSecretKey,{expiresIn:config.expiresIn})// 响应给客户端,token的bearer后面有空格,别丢res.send({status:1,message:'登录成功',token:'Bearer '+tokenstr})})
}
配置解析JWT的token字符串的中间件
  • 作用:用来解析客户端传过来的token
  • 安装中间件
npm i express-jwt@5.3.3
  • 一定要在app.js中注册路由之前,配置解析token的中间件
// 导入配置文件
const config = require('./config')
// 导入解析token的中间件
const expressJWT = require('express-jwt')
// 使用.unless可以指定哪些接口不需要toke身份验证,演示以api开头的
app.use(expressJWT({secret: config.jwtSecretKey
}).unless({path: [/^\/api\//]
}))
  • 全局错误中间件,捕获解析失败的错误
app.use((err, req, res, next) => {// 捕获token解析失败的错误if (err.name === 'UnauthorizedError') return res.cc('身份验证失败')res.cc(err)next()
})

相关文章:

【Node.js】项目开发实战(中)

开发用户的注册和登录接口步骤1,打开MySQL Workbench,打开自己的数据库进入创建用户信息表新建 ev_users表安装并配置mysql模块安装mysql模块新建db文件夹下index.js,导入并配置mysql模块安装bcryptjs对密码进行加密处理新建/router_handler/user.js中&a…...

记录一次 New Bing 英语陪练

记录一次 New Bing 英语陪练 Now I start to speak english to chat with you . Help me find the mistake in my word and help me improve my english I’m glad you want to practice your English with me. I can help you find the mistakes in your words and help you i…...

【Python】照片居然能变素描?不会画画但是咱会代码

文章目录前言一、准备二、下载预训练模型总结前言 Photo-Sketching 一个能将照片的轮廓识别出来并将其转化为“速写”型图像的开源模块。 比如,这只小狗: 经过模型的转化,会变成卡通版的小狗: 非常秀,这很人工智能…...

已解决正确配置git环境变量

已解决git没有配置环境变量,抛出异常ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH?,附上正确配置git环境变量的教程 文章目录报错问题报错翻译报错原因解决方法《100天精通Python》专栏推荐白嫖80g Python全栈…...

【逐步剖C】-第十章-自定义类型之结构体、枚举、联合

一、结构体 前言:有关结构体的声明、定义、初始化以及结构体的传参等结构体的基本使用在文章【逐步剖C】-第六章-结构体初阶中已进行了详细的介绍,需要的朋友们可以看看。这里主要讲解的是有关结构体的内存问题。 1. 结构体的内存对齐 (1&…...

Windows Server 2016 中文版、英文版下载 (updated Mar 2023)

Windows Server 2016 Version 1607,2023 年 3 月更新 请访问原文链接:https://sysin.org/blog/windows-server-2016/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 本站将不定期发布官方原版风格月度更…...

Linux 4G 通信实验

目录4G 网络连接简介高新兴ME3630 4G 模块实验ME3630 4G 模块简介ME3630 4G 模块驱动修改ME3630 4G 模块ppp 联网测试前面我们学习了如何在Linux 中使用有线网络或者WIFI,但是使用有线网络或者WIFI 有 很多限制,因为要布线,即使是WIFI 你也得…...

华为OSPF技术详细介绍,保姆级,谁都能看懂(一)

目录 1、简介 2、OSPF基本原理 3、OSPF的特点 4、OSPF区域 5、路由器的类型 6、OSPF5种报文 7、后半部分内容 1、简介 OSPF(Open Shortest Path First,开放最短路径优先)是一个基于链路状态的内部网关协 议。目前针对IPv4协议使用的是OS…...

行人车辆检测与计数系统(Python+YOLOv5深度学习模型+清新界面)

摘要:行人车辆检测与计数系统用于交通路口行人及车辆检测计数,道路人流量、车流量智能监测,方便记录、显示、查看和保存检测结果。本文详细介绍行人车辆检测,在介绍算法原理的同时,给出Python的实现代码、PyQt的UI界面…...

SM3哈希算法的FPGA实现 I

SM3哈希算法的FPGA实现 I SM3哈希算法的FPGA实现 I一、什么是SM3哈希算法?二、SM3哈希算法的具体内容1、填充2、迭代与压缩3、计算拼凑值三、参考文档语言 :verilog 仿真工具: Modelsim EDA工具:quartus II 一、什么是SM3哈希算法…...

【数据结构与算法】线性表--数组

文章目录一、前言二、数组的概念三、数组的操作数组的插入数组的删除四、容器与数组五、问题:为何数组要从0开始编号,而不是1开始呢?六、总结一、前言 常见的数据结构如下图,本文主要讲解数据结构线性表--数组。 二、数组的概念 …...

剑指offer排序专题

剑指offer排序专题 jz3 数组中重复的数字描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[…...

已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py

已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py 文章目录报错问题报错翻译报错原因解决方法1:easy_install 来安装pip解决方法2:本地安装pip《100天精通Python》专栏推荐白嫖80g Python全栈视频报错问题 粉丝群里面的一个小伙伴遇到问题…...

3 步走,快速上手 API 接口测试

开始 API 接口测试之前,我们需要弄清接口测试的含义: 接口测试就是根据接口清单,模拟客户端向服务端发送请求数据,并获取响应数据后,查看响应数据是否符合预期的过程。 整个过程可以分为三个步骤: 第一步&…...

爬虫-day1-正则表达式作业

利用正则表达式完成下面的操作: 一、不定项选择题 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括(ABD ) A. r"\(?\d{3}\)?-?\d{8}" B. r"[0-9()-]" C. r"[0-9(-)]*\d*&…...

【半监督医学图像分割 2023 CVPR】RCPS

文章目录【半监督医学图像分割 2022 CVPR】RCPS摘要1. 介绍2. 相关工作2.1 医学图像分割2.1 半监督学习2.3 对比学习3. 方法3.1 整体概述3.2 纠正伪监督3.3 双向Voxel对比学习。4. 实验【半监督医学图像分割 2022 CVPR】RCPS 论文题目:RCPS: Rectified Contrastive …...

【UVM实战练习项目】2、UVM验证环境基本框架搭建(实例一)(纯软件环境,方便日后测试使用)

本节基于DUT完成UVM验证环境的基本框架搭建,实现对UVM理论知识点进行巩固练习,具体内容包括:如何创建激励、如何建立sequencer、如何连接sequencer和driver,如何集成agent、如何构建env等。 正式开始之前让我们再来回顾下搭建验证环境的过程:首先进行数据建模sequence_ite…...

【web前端初级课程】第四章 什么是JavaScript

目录 一、JavaScript在前端的三种写法 二、常见的弹框 三、变量 四、常量 五、数据类型 六、运算符 七、循环及函数 八、相关练习 前言 JavaScript是一个面向对象的,弱数据类型的,解释型的,动态脚本语言。 面向对象更符合我们对事物…...

数字中国建设进行时:吉林大学党委常务副书记冯正玉一行调研实在智能

两会前夕,中共中央、国务院印发了《数字中国建设整体布局规划》,明确了加快数字中国建设的重点任务。《规划》强调,要加强整体谋划、统筹推进,把各项任务落到实处。在强化人才支撑的第四要点上,指出统筹布局一批数字领…...

面试官灵魂拷问[二]:SQL 语句中 where 条件后写上 1=1 是什么意思?

面试官灵魂拷问系列又来更新啦! “SQL 语句中 where 条件后写上 11 是什么意思?” 这玩意就跟很多新语言支持尾部逗号的原理一样的。 比如 Kotlin 支持数组写成 [1, 2, 3, 4, ] ,注意4后边那个逗号,为什么呢?因为当你增加一个项…...

【kafka】Golang实现分布式Masscan任务调度系统

要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【2025年】解决Burpsuite抓不到https包的问题

环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

【Oracle】分区表

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

深度学习习题2

1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...