node.js(express.js)+mysql实现登录功能

文章目录

  • 前言
      • 实现步骤
  • 实现步骤
      • 一、检测登录表单的数据是否合法
        • (3)新建schema/user.js
        • (4)在routes/use.js中引入schema/user.js中的方法reg_login_schema,代码如下:
      • 二、根据用户名查询用户的数据
      • 三、判断用户输入的密码是否正确
      • 四、生成JWT 的 Token 字符串
  • 最终登录接口代码如下:
      • 五、在app.js中注册路由之前,配置解析token的中间件,为了指定那些接口不需要进行Token 的身份认证


前言

实现步骤

1.检测表单数据是否合法
2.根据用户名查询用户的数据
3.判断用户输入的密码是否正确
4.生成JWT 的 Token 字符串


登录接口完整代码如下:controllers/user.js文件

// 登录接口
var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");
// 导入jwt 包来生成token
const jwt = require("jsonwebtoken");
// 导入密钥
const config = require("../config");
exports.login = (req, res) => {// 获取客户端提交到服务器的用户信息const userinfo = req.body;// 定义sql语句,根据用户名查询用户的信息const sql = `select * from ev_users where username=?`;// 执行sql语句,根据用户名查询用户的信息db.query(sql, userinfo.username, (err, results) => {// 执行sql语句失败if (err) return res.cc(err);// 执行sql语句成功,但是获取到的数据条件不等于1if (results.length !== 1) return res.cc("登录失败!");// 判断密码是否和数据库中的密码是否一致// compareSync 第一个参数用户输入的,第二个参数数据库查询到的// 返回值为ture 一致,反之const compareResult = bcrypt.compareSync(userinfo.password,results[0].password);console.log("1", userinfo.password);console.log("2", results[0].password);if (!compareResult) {return res.cc("登录失败233");}// 生成jwt的token字符串// 清空用户信息的密码和头像const user = { ...results[0], password: "", user_pic: "" };console.log(user);// 对用户的信息进行加密,生成token字符串const tokenStr = jwt.sign(user, config.jwtSecretKey, {expiresIn: "10h", // token 有效期为10小时});// 将生成的token字符串响应给客户端res.send({status: 0,message: "登录成功!",// 为了方便客户端使用,在服务器端直接拼接上Bearer的前缀// 注意:Bearer 后面必须有空格token: "Bearer "+ tokenStr,});// res.cc("ok");});
};

实现步骤

一、检测登录表单的数据是否合法

1)安装 jOi 包,为表单中携带的每个数据项,定义验证规则:

npm install joi

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

npm install @escook/express-joi
(3)新建schema/user.js
// 导入定义验证规则的包
// const joi = require("@hapi/joi");
const joi = require("joi");
/*** string()值必须是字符串* alphanum()值只能包含a-zA-ZO-9的字符串* min(length) 最小长度* max(length) 大长度* required() 值是必填项,不能为 undefined* pattern(正则表达式) 值必须符合正则表达式的规则*/// 定义用户名和密码的验证规则
const username = joi.string().alphanum().min(1).max(10).required();
const password = joi.string().pattern(/^[\S]{6,12}$/).required();
// 定义验证注册和登录表单数据的规则对象
exports.reg_login_schema = {body: {username,password,},
};
(4)在routes/use.js中引入schema/user.js中的方法reg_login_schema,代码如下:
var express = require("express");
var router = express.Router();
// 引入封装的获取验证码的方法
var unr_handler = require("../controllers/user");// 1.导入验证数据的中间件
const expressJoi = require("@escook/express-joi");
//  2.导入需要的验证规则对象
const { reg_login_schema } = require("../schema/user");// 新用户注册
// router.post("/regUser", expressJoi(reg_login_schema), unr_handler.regUser);
// router.post("/regUser", unr_handler.regUser);
// 登录
router.post("/login", expressJoi(reg_login_schema), unr_handler.login);
module.exports = router;

二、根据用户名查询用户的数据

var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");
// 导入jwt 包来生成token
const jwt = require("jsonwebtoken");
// 导入密钥
const config = require("../config");
// 登录接口
exports.login = (req, res) => {// 获取客户端提交到服务器的用户信息const userinfo = req.body;// 定义sql语句,根据用户名查询用户的信息const sql = `select * from ev_users where username=?`;// 执行sql语句,根据用户名查询用户的信息db.query(sql, userinfo.username, (err, results) => {// 执行sql语句失败if (err) return res.cc(err);// 执行sql语句成功,但是获取到的数据条件不等于1if (results.length !== 1) return res.cc("登录失败!");// res.cc("ok");});
};

三、判断用户输入的密码是否正确

// 导入密码加密
const bcrypt = require("bcryptjs");
exports.login = (req, res) => {// 获取客户端提交到服务器的用户信息const userinfo = req.body;// 定义sql语句,根据用户名查询用户的信息const sql = `select * from ev_users where username=?`;// 执行sql语句,根据用户名查询用户的信息db.query(sql, userinfo.username, (err, results) => {// 执行sql语句失败if (err) return res.cc(err);// 执行sql语句成功,但是获取到的数据条件不等于1if (results.length !== 1) return res.cc("登录失败!");// 判断密码是否和数据库中的密码是否一致// compareSync 第一个参数用户输入的,第二个参数数据库查询到的// 返回值为ture 一致,反之const compareResult = bcrypt.compareSync(userinfo.password,results[0].password);console.log("1", userinfo.password);console.log("2", results[0].password);if (!compareResult) {return res.cc("登录失败233");}// res.cc("ok");});
};

四、生成JWT 的 Token 字符串

1)在生成 Token 字符串的时候,一定要别除 密码 和 头像 的值

  // 清空用户信息的密码和头像const user = { ...results[0], password: "", user_pic: "" };

2)安装成成token的字符串包

npm 1 jsonwebtoken@8.5.1

3)在 /controllers/user.js 模块的头部区域,导入 jsonwebtoken 包:

// 导入jwt 包来生成token
const jwt = require("jsonwebtoken");

4)创建 config.js 文件,并向外共享加密和还原Token 的 jwtSecretKey 字符串:

// 全局的配置文件
module.exports = {// 加密和解密 token 的密钥jwtSecretKey: "itheima No1. ^_^",
};

5)将用户信息对象加密成 Token 字符串, 在controllers/user.js文件引入config.js

// 导入密钥
const config = require("../config");
const user = { ...results[0], password: "", user_pic: "" };console.log(user);// 对用户的信息进行加密,生成token字符串const tokenStr = jwt.sign(user, config.jwtSecretKey, {expiresIn: "10h", // token 有效期为10小时});// 将生成的token字符串响应给客户端res.send({status: 0,message: "登录成功!",// 为了方便客户端使用,在服务器端直接拼接上Bearer的前缀token: "Bearer"+ tokenStr,});

最终登录接口代码如下:

// 登录接口
var db = require("../utils/db"); 
// 导入密码加密
const bcrypt = require("bcryptjs");
// 导入jwt 包来生成token
const jwt = require("jsonwebtoken");
// 导入密钥
const config = require("../config");
exports.login = (req, res) => {// 获取客户端提交到服务器的用户信息const userinfo = req.body;// 定义sql语句,根据用户名查询用户的信息const sql = `select * from ev_users where username=?`;// 执行sql语句,根据用户名查询用户的信息db.query(sql, userinfo.username, (err, results) => {// 执行sql语句失败if (err) return res.cc(err);// 执行sql语句成功,但是获取到的数据条件不等于1if (results.length !== 1) return res.cc("登录失败!");// 判断密码是否和数据库中的密码是否一致// compareSync 第一个参数用户输入的,第二个参数数据库查询到的// 返回值为ture 一致,反之const compareResult = bcrypt.compareSync(userinfo.password,results[0].password);console.log("1", userinfo.password);console.log("2", results[0].password);if (!compareResult) {return res.cc("登录失败233");}// 生成jwt的token字符串// 清空用户信息的密码和头像const user = { ...results[0], password: "", user_pic: "" };console.log(user);// 对用户的信息进行加密,生成token字符串const tokenStr = jwt.sign(user, config.jwtSecretKey, {expiresIn: "10h", // token 有效期为10小时});// 将生成的token字符串响应给客户端res.send({status: 0,message: "登录成功!",// 为了方便客户端使用,在服务器端直接拼接上Bearer的前缀// 注意:Bearer 后面必须有空格token: "Bearer "+ tokenStr,});// res.cc("ok");});
};

/utils/db文件代码

const mysql = require("mysql");
const db = mysql.createPool({host: "localhost", // 连接地址port: "3306", //端口号user: "root", //用户名password: "XXXXXXX", //密码database: "exapp2", //数据库名
});
module.exports = db;

在这里插入图片描述

五、在app.js中注册路由之前,配置解析token的中间件,为了指定那些接口不需要进行Token 的身份认证

1.安装解析 Token 的中间件:

npm i express-jwt@5.3.3

2). app.js

// 导入配置文件
const config = require("./config");
// 解析token的中间件
const expressJWT = require("express-jwt");
// 使用 unless({ path:[/^\/user\//] )) 指定哪些接口不需要进行 Token 的身份认证
// ps: path: [/^\/user/] 改成你自己的接口前缀path: [/^\/XXX/] 
app.use(expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/user/] })
);

3)在 app.js 中的 错误级别中间件 里面,捕获并处理 Token 认证失败后的错误:

// 定义表单验证失败的错误的中间件,并把验证失败的结果响应给客户端
// 错误中间件
app.use(function (err, req, res, next) {// 数据验证失败,instanceof判断if (err instanceof joi.ValidationError) {return res.cc(err);}// token身份认证失败后的错误if (err.name === "UnauthorizedError") return res.cc("身份认证失败");// 未知错误res.cc(err);
});

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

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

相关文章

Python 生成 图片网页列表 显示路径和建立时间 笔记

Python 一键 生成 图片网页列表 显示路径和建立时间 (方便查看复制路径、重复一键生成) 支持格式:jpg \png\ svg\ webp 图片网页列表 图示: 参考代码: # -*- coding: utf-8 -*- import os import datetime# 指定图片…

【Linux对磁盘进行清理、重建、配置文件系统和挂载,进行系统存储管理调整存储结构】

Linux 调整存储结构 前言一、查看磁盘和分区列表二、创建 ext4 文件系统,即:格式化分区为ext4文件系统。1.使用命令 mkfs.ext4 (make file system)报错如下:解决办法1:(经测试,不采用)X解决办法…

浅谈大数据智能化技术在多个领域的应用实践

摘要 大数据智能化技术在当今信息社会中得到了广泛的应用。从金融、互联网电商、视频行业到垂直短视频领域,从工业互联网到云计算、边缘计算等领域,大数据智能化技术已经成为了企业竞争力的重要组成部分。技术实践、架构设计、指标体系、数据质量、数据分…

APP 用户转化率低流失率高?可能您需要了解下这个!

如今手机的性能和内存在突飞猛进,但用户的时间和精力是有限的。根据《 2020 年中国移动 APP 行业分析报告》,在 2019 年 Q4,头部企业所占据手机用户的时长份额已经达到 70.7%。 APP 市场竞争激烈,获客难度和成本在上升&#xff0…

阿里云ECS(CentOS镜像)安装docker

目录 1.前置条件 2.连接至ECS 3.yum软件包更新 4.安装docker前置所需软件包 5.添加docker 官方的 yum 软件源 6.安装docker 7.检测是否成功 8.配置阿里云镜像加速器 1.前置条件 在看本文前保证未安装过docker,或者安装过但是清理干净 如果多次安装失败过,…

网络编程 day6

网络聊天室项目 1.服务器端 #include <head.h> #define SER_IP "192.168.125.11" #define SER_PORT 6666 typedef struct Msg {char user[32]; //用户名int type; //1.登录、2.发消息、0.退出char text[1024]; //消息 } msg_t; typedef struct List…

高德地图官方首度揭秘:红绿灯倒计时功能是如何实现的?

今年元旦&#xff0c;小编喜提新车后&#xff0c;第一次使用高德地图 App 驾车模式&#xff0c;在路口等红灯时立刻被红绿灯倒计时读秒功能惊艳了&#xff0c;竟能够准确地显示红绿灯的剩余时间&#xff01;好奇心驱使我&#xff0c;不禁想弄明白怎么神奇的功能是如何实现的呢&…

SSL通配符免费申请

通配符SSL证书是一种可以用于保护主域名及其所有子域名的证书。通配符SSL证书使用通配符&#xff08;*&#xff09;来代表所有子域名&#xff0c;使得只需一个证书就可以覆盖多个子域名。 要申请通配符SSL证书&#xff0c;您可以按照以下步骤进行&#xff1a; 选择SSL证书提供…

结构体的内存对齐(计算题常考点)

许久不见我考完试回来啦&#xff0c;让我们接着将结构体进行到底&#xff01; 目录 结构体对齐的意义&#xff1a; 结构体对齐的实现&#xff1a; 对齐规则&#xff1a; 训练&#xff1a; 好到这里误区来了&#xff1a; 总结&#xff1a; 往期回顾&#xff1a; 下期预告&…

机器学习周记(第二十六周:文献阅读-DPGCN)2024.1.15~2024.1.21

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文背景 2 论文模型 2.1 问题描述 2.2 论文模型 2.2.1 时间感知离散图结构估计&#xff08;Time-aware Discrete Graph Structure Estimation Module&#xff0c;TADG Module&#xff09; 2.2.2 时间…

html 会跳舞的时间动画特效

下面是是代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta h…

LeetCode 77. 组合

77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2&#xff1a; 输入&#xff1a;…

说说你对归并排序的理解?如何实现?应用场景?

一、是什么 归并排序&#xff08;Merge Sort&#xff09;是建立归并操作上的一种有效&#xff0c;稳定的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序&#xff0c;再使…

nodejs下载安装

一、node下载安装 官网下载 官网 根据自己电脑系统选择合适的版本进行下载&#xff0c;我这里选择window 64 位 下载完点击安装 打开cmd查看安装 此处说明下&#xff1a;新版的Node.js已自带npm&#xff0c;安装Node.js时会一起安装&#xff0c;npm的作用就是对Node.js…

Go使用记忆化搜索的套路【以20240121力扣每日一题为例】

题目 分析 这道题很明显记忆化搜索&#xff0c;用py很容易写出来 Python class Solution:def splitArray(self, nums: List[int], k: int) -> int:n len(nums)# 寻找分割子数组中和的最小的最大值s [0]for num in nums:s.append(s[-1] num)#print(s)cachedef dfs(cur,…

Spring boot项目java bean和xml互转

Spring boot项目实现java bean和xml互转 项目场景&#xff1a;互转方法使用jackson进行互转使用jaxws进行xml与bean的互转 搞定收工&#xff01; 项目场景&#xff1a; 工作中需要给下游第三方收费系统做数据挡板&#xff0c;由于下游系统使用的是soap webservice,里面涉及各种…

第91讲:MySQL主从复制集群主库与从库状态信息的含义

文章目录 1.主从复制集群正常状态信息2.从库状态信息中重要参数的含义 1.主从复制集群正常状态信息 通过以下命令查看主库的状态信息。 mysql> show processlist;在主库中查询当前数据库中的进程&#xff0c;看到Master has sent all binlog to slave; waiting for more u…

《WebKit 技术内幕》之六(3): CSS解释器和样式布局

3 WebKit布局 3.1 基础 当WebKit创建RenderObject对象之后&#xff0c;每个对象是不知道自己的位置、大小等信息的&#xff0c;WebKit根据框模型来计算它们的位置、大小等信息的过程称为布局计算&#xff08;或者称为排版&#xff09;。 图描述了这一过程中涉及的主要WebKit…

【解决方法】PPT不能编辑,按钮都是灰色,怎么办?

PPT文件打开之后&#xff0c;发现无法编辑&#xff0c;再仔细查看发现工具栏中的功能按钮都是灰色的&#xff0c;无法使用&#xff0c;这是什么原因&#xff1f;该如何解决&#xff1f; 原因&#xff1a;无法编辑PPT文件&#xff0c;并且功能按钮都是灰色&#xff0c;这是因为…

qnx 上screen + egl + opengles 最简实例

文章目录 前言一、qnx 上的窗口系统——screen二、screen + egl + opengles 最简实例1.使用 addvariant 命令创建工程目录2. 添加源码文件3. common.mk 文件4. 编译与执行总结参考资料前言 本文主要介绍如何在QNX 系统上使用egl和opengles 控制GPU渲染一个三角形并显示到屏幕上…