Node编写用户登录接口

目录

前言

服务器

编写登录接口API

使用sql语句查询数据库中是否有该用户

判断密码是否正确

生成JWT的Token字符串

配置解析token的中间件

配置捕获错误中间件

完整的登录接口代码


前言

本文介绍如何使用node编写登录接口以及解密生成token,如何编写注册接口已经在Node编写用户注册接口这篇文章中介绍,本文是建立在编写注册接口这篇文章的基础之上

同时也可以在在前端html页面中向服务器发送post登录请求这篇文章中了解登录请求

服务器

关于创建服务器,本文中和Node编写用户注册接口共用一个服务器,已经引入了router对象

// 导入express模块
const express = require('express')// 创建express服务器实例
const app = express()// 导入跨域cors
const cors = require('cors')// 全局挂载
app.use(cors())// 配置解析表单数据中间件
app.use(express.urlencoded({extended:false}))// 导入用户路由对象
const userRouter = require('./router/user')
app.use('/api',userRouter)// 启动服务器
app.listen(3007,()=> {console.log('running the http://127.0.0.1:3007');
})

编写登录接口API

使用sql语句查询数据库中是否有该用户
const userinfo = req.bodyconst sql = 'select * from ev_users where username = ?'db.query(sql, userinfo.username, function (err, results) {// 执行 SQL 语句失败if (err) {return res.send({status:1,message:err.message})}// 执行 SQL 语句成功,但是查询到数据条数不等于 1if (results.length !== 1) {return res.send({status:1,message:'登录失败'})}res.send('登录成功')})

使用postman模拟发送登录请求,查询是否有用户名为b

返回登录成功

数据库中有b用户

如果未注册

数据库中没有c用户

判断密码是否正确

调用了bcrypt.compareSync()方法,用来解密,因为在注册时已经把密码加密了,所以需要解密

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

// 判断密码是否正确const compareResult = bcrypt.compareSync(userinfo.password,results[0].password)if(!compareResult) return res.send({status:1,message:'密码错误'})res.send('登录成功')

验证b的密码是否正确

b的密码是000000

当把b的密码换成111111时,也就是错误密码

返回密码错误

生成JWT的Token字符串

关于JWT认证,可以浏览JWT认证这篇文章

生成token字符串时,要把密码和用户头像剔除,因为生成的token会保留在浏览器中,很容易泄露

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

先安装jsonwebtoken

npm i jsonwebtoken

导入jwt

const jwt = require('jsonwebtoken')

导入成功后调用jwt.sign()生成JWT字符串

jwt.sign(用户的信息,加密的密钥,配置对象有效token的时间)

// 生成 Token 字符串const tokenStr = jwt.sign(user, jwtSecreKey, {expiresIn: '10h', // token 有效期为 10 个小时})

将生成的token字符串发送给客户端

在生成的的token字符串前拼接上"Bearer",固定用法

res.send({status: 0,message: '登录成功!',// 为了方便客户端使用 Token,在服务器端直接拼接上 Bearer 的前缀token: 'Bearer ' + tokenStr,})

使用postman模拟发送请求

配置解析token的中间件

将jwt字符串还原为JSON对象,在get请求时,可以获得用户信息

安装express-jwt

npm i express-jwt

导入

/ 导入解析token字符串
const exoressjwt = require('express-jwt')

解析token

// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(expressjwt.expressjwt({secret:jwtSecreKey,algorithms:['HS256'],
}).unless({path:[/^\/api\//]}))
配置捕获错误中间件
// 错误中间件
app.use(function (err, req, res, next) {// 捕获身份认证失败的错误if (err.name === 'UnauthorizedError') return res.send({satus:1,message:'身份认证失败'})// 未知错误res.send({status:1,message:err.message})})

完整的登录接口代码

// 导入express模块
const express = require('express')
// 导入数据库对象
const db = require('../db/index')// 导入加密模块
const bcrypt = require('bcryptjs')// 创建路由对象
const router = express.Router()// 导入JWT
const jwt = require('jsonwebtoken')
// 定义密钥
const jwtSecreKey = 'notbald'// 登录接口
router.post('/login',(req,res)=>{const userinfo = req.bodyconst sql = 'select * from ev_users where username = ?'db.query(sql, userinfo.username, function (err, results) {// 执行 SQL 语句失败if (err) {return res.send({status:1,message:err.message})}// 执行 SQL 语句成功,但是查询到数据条数不等于 1if (results.length !== 1) {return res.send({status:1,message:'登录失败'})}// 判断密码是否正确const compareResult = bcrypt.compareSync(userinfo.password,results[0].password)if(!compareResult) return res.send({status:1,message:'密码错误'})// 生成token字符串,展开运算符,剔除密码和用户头像const user = {...results[0],password:'',user_pic:''}// console.log(user);// 生成 Token 字符串const tokenStr = jwt.sign(user, jwtSecreKey, {expiresIn: '10h', // token 有效期为 10 个小时})res.send({status: 0,message: '登录成功!',// 为了方便客户端使用 Token,在服务器端直接拼接上 Bearer 的前缀token: 'Bearer ' + tokenStr,})})
})

解析token以及全局捕获错误中间件在服务器中

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

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

相关文章

关于 硬盘

关于 硬盘 1. 机械硬盘1.1 基本概念1.2 工作原理1.3 寻址方式1.4 磁盘磁记录方式 2. 固态硬盘2.1 基本概念2.2 工作原理 1. 机械硬盘 1.1 基本概念 机械硬盘即是传统普通硬盘,硬盘的物理结构一般由磁头与盘片、电动机、主控芯片与排线等部件组成。 所有的数据都是…

利用dns协议发起ddos反射攻击

利用DNS服务器发起反射型DDOS,攻击带宽 基本思路: 1、利用any类型的dns查询,可完成发送少量请求数据,获得大量返回数据。 2、将原请求地址改为受害者地址,则dns会向受害者返回大量数据,占用带宽 警告&…

c# ManualResetEvent WaitHandle 实现同步

//本文演示了ManualResetEvent 类的非静态set()、Reset()、WaitOne()和 //WaitHandle类的静态方法WaitAllWaitAll() //它们用于线程间的同步控制。 //实现了如下功能:线程1(定时控制)通知线程2和线程3采集数据 //线程2和3数据采集完了&am…

QCC 音频输入输出

QCC 音频输入输出 QCC蓝牙芯片(QCC3040 QCC3083 QCC3084 QCC5181 等等)支持DAC、I2S、SPDIF输出,AUX、I2S、SPDIF、A2DP 输入 蓝牙音频输入,模拟输出是最常见的方式。 也可以再此基础上动态切换输入方式。 输入方式切换参考 sta…

POJ 3470 Walls 树上分桶

今天太晚了&#xff0c;代码先发上&#xff0c;思路明天说吧。 陌上花开&#xff0c;树上分桶 #include <iostream> #include <algorithm> #include <vector> using namespace std; /*** 对于y1不等于y2的&#xff0c;可以用datC求解&#xff0c;对于x1不等…

AD9371 官方例程HDL详解之JESD204B TX侧时钟生成 (一)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 梳理 AD9371 时钟&#xff0c;理解采样率和各个时钟之间的关系 …

linux nginx1.24.0安装

nginx高性能web服务器&#xff0c;可作为一般http应用转发&#xff0c;也可以做mySql、redis、zk、rabbit MQ等tcp数据流转发。 常用Linux服务系统centos和ububtu 只是安装命令不同 yum/apt-get&#xff0c;流程和依赖包是一样的安装方式 1、下载nginx安装包tar.gz官方下载地…

RabbitMQ基础篇 笔记

RabbitMQ 余额支付 同步调用 一步一步的来&#xff0c;支付业务写完后&#xff0c;如果之后加需求&#xff0c;还需要增加代码&#xff0c;不符合开闭原则。 性能上也有问题&#xff0c;openfeign是同步调用&#xff0c;性能太差。 同步调用耦合太多。 同步的优势是可以立…

网站、小程序常见布局样式记录

文章目录 &#x1f380;前言&#xff1a;&#x1f415;网页样式展示小程序&#xff1a;《携程网》&#x1f380;持续更新... &#x1f380;前言&#xff1a; 本篇博客会收藏一些作者见到的网页、小程序页面&#xff0c;目的是用来寻找制作项目网页页面的灵感&#xff0c;有需要…

mysql第一篇---索引

文章目录 mysql第一篇---索引索引的数据结构为什么使用索引&#xff1f;索引的及其优缺点InnoDB中索引的推演常见的索引概念InnoDB的B树索引的注意事项MyISAM中索引方案索引的代价MySQL数据结构选择的合理性 mysql第一篇—索引 索引的数据结构 为什么使用索引&#xff1f; 索…

修炼k8s+flink+hdfs+dlink(六:学习k8s-pod)

一&#xff1a;增&#xff08;创建&#xff09;。 直接进行创建。 kubectl run nginx --imagenginx使用yaml清单方式进行创建。 直接创建方式&#xff0c;并建立pod。 kubectl create deployment my-nginx-deployment --imagenginx:latest 先创建employment&#xff0c;不…

华为OD 高效的任务规划(200分)【java】A卷+B卷

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…

紫光展锐携中国联通完成RedCap芯片V517孵化测试

近日&#xff0c;紫光展锐携手中国联通5G物联网OPENLAB开放实验室&#xff08;简称“OPENLAB实验室”&#xff09;共同完成RedCap芯片V517创新孵化&#xff0c;并实现在联通5G全频段3.5GHz、2.1GHz、900MHz下的端到端业务验证测试。 V517是一款基于紫光展锐5G成熟平台设计与研发…

oninput和onchange事件有什么区别以及使用场景

oninput和onchange都是常见的表单元素的事件&#xff0c;它们的区别在于触发的时机不同。 oninput事件会在表单元素的值发生变化时立刻触发&#xff0c;无论是通过键盘输入、粘贴、剪切、拖拽等方式&#xff0c;都能实时响应。比如&#xff1a; <input type"text&quo…

Java反射实体组装SQL

之前在LIS.Core定义了实体特性&#xff0c;在LIS.Model给实体类加了表特性&#xff0c;属性特性&#xff0c;外键特性等。ORM要实现增删改查和查带外键的父表信息就需要解析Model的特性和实体信息组装SQL来供数据库驱动实现增删改查功能。 实现实体得到SQL的工具类&#xff0c…

DOS攻击-ftp_fuzz.py

搭建FTP 使用AlphaFuzzer的FTPFUSS进行攻击 挖掘漏洞&#xff0c;自动用特殊字符看能不能把服务器崩掉 这些都是测试的目录 不能随意使用&#xff0c;可能会把C盘内容清掉 也可以自己写脚本测试下

二叉排序树(BST)

二叉排序树 基本介绍 二叉排序树创建和遍历 class Node:"""创建 Node 节点"""value: int 0left Noneright Nonedef __init__(self, value: int):self.value valuedef add(self, node):"""添加节点node 表示要添加的节点&quo…

使用CMakeLists.txt简化项目构建过程

在软件开发过程中&#xff0c;项目的构建是一个不可避免的环节。而随着项目规模的增大&#xff0c;手动管理编译过程变得越来越繁琐。为了简化构建流程并实现跨平台支持&#xff0c;CMake作为一种流行的构建系统被广泛采用。本文将介绍CMakeLists.txt文件的结构&#xff0c;以及…

读书笔记:Effective C++ 2.0 版,条款28(namespace )

条款28: 划分全局名字空间 namespace 作为前缀&#xff0c;防止不同名字域的类型、常量等互相污染。 没命名的名字空间一般用于限制名字空间内部元素的可见性。 namespace sdm {const double book_version 2.0;class handle { ... };handle& gethandle(); }早期用struct模…

使用序列化技术保存数据 改进 IO流完成项目实战水果库存系统

上一节内容是 使用IO流完成项目实战水果库存系统https://blog.csdn.net/m0_65152767/article/details/133999972?spm1001.2014.3001.5501 package com.csdn.fruit.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java…