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.body
    const 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 语句成功,但是查询到数据条数不等于 1
        if (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.body
    const 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 语句成功,但是查询到数据条数不等于 1
        if (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.mfbz.cn/a/105512.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【VUE】ElementPlus之动态主题色调切换(Vue3 + Element Plus+Scss + Pinia)

前言 关于ElementPlus的基础主题色自定义可以参阅《【VUE】ElementPlus之自定义主题样式和命名空间》 有了上面基础的了解,我们知道ElementPlus的主题色调是基于CSS3变量特性进行全局控制的, 那么接下来我们也基于CSS3变量来实现主题色调的动态切换效果&…

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

Python字典-dict “ “ ---记一次查缺补漏“ “

文章目录 0x0 前言0x1 字典 (Dictionary)0x01 访问字典里的值0x02 修改字典0x03 删除字典元素0x04 判断字典是否包含指定key,用in或not in 运算符 0x2 字典键的特性0x010x2 0x3 字典内置函数&方法0x4 使用格式化字符串 0x0 前言 python没…

Kotlin(九) 集合以及集合API

目录 一:集合的创建 List 集合的创建: 集合的遍历: Set Map 创建 遍历 二:集合的函数式API maxBy函数 map函数 filter函数 any和all函数 一:集合的创建 List 集合的创建: ① listOf() 不…

Visual Studio Code (VS Code)安装教程

Visual Studio Code(简称“VS Code”)。 1.下载安装包 VS Code的官网: Visual Studio Code - Code Editing. Redefined 首先提及一下,vscode是不需要破解操作的; 第一步,看好版本,由于我的系…

网络协议--BOOTP:引导程序协议

16.1 引言 在第5章我们介绍了一个无盘系统,它在不知道自身IP地址的情况下,在进行系统引导时能够通过RARP来获取它的IP地址。然而使用RARP有两个问题:(1)IP地址是返回的唯一结果;(2)…

031-从零搭建微服务-监控中心(一)

写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):mingyue: 🎉 基于 Spring Boot、Spring Cloud & Alibaba 的分布式微服务架构基础服务中心 源…

「实用技巧」后端如何使用 Eolink Apikit 快速调试接口?

程序员最讨厌的两件事: 写文档 别人不写文档 写文档、维护文档比较麻烦,而且费时,还会经常出现 API 更新了,但文档还是旧的,各种同步不一致的情况,从而耽搁彼此的时间,大多数开发人员不愿意写…

学习笔记-MongoDB(命令增删改查,聚合,权限管理,索引,java使用)

基础概念 1 什么是mogodb? MongoDB 是一个基于分布式文件/文档存储的数据库,由 C 编写,可以为 Web 应用提供可扩展、高性能、易部署的数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功…

并发编程- 线程池ForkJoinPool工作原理分析(实践)

数据结构加油站: Comparison Sorting Visualization 并发设计模式 单线程归并排序 public class MergeSort {private final int[] arrayToSort; //要排序的数组private final int threshold; //拆分的阈值,低于此阈值就不再进行拆分public MergeSort…

haproxy 负载均衡

haproxy负载均衡 haproxy:基于C语言开发的开源软件 支持高性能的tcp和http负载均衡器,工作中用的版本1.5.9 haproxy功能:主要用于高并发的web站点,工作原理和nginx、lvs都一样 haproxy缺点: 单节点部署,单实例运行。代…

【postman】postman的使用与postman汉化

postman的使用 Postman 是一个接口测试工具软件,可以帮助开发人员管理测试接口。 官网:Postman API Platform psotman环境 首先import的或则new 创建一个环境 Variable 变量名 Type 类型 Initial value 初始值 C…

prometheus监控kafka

一、前言 关于对kafka的监控,要求高的话可以使用kafka-exorter和jmx-exporter一起收集监控数据,要求不高的情况下可以使用kafka-exporter收集监控数据即可 二、部署 kafka-exporter 部署kafka-exporter,我是在k8s集群中部署的 编辑yaml文件…

D71X-16Q手柄蝶阀型号解析

D71X-16Q型号字母含义解析 D71X-16Q是德特森阀门常用的手柄蝶阀型号字母分别代表的意思是: D——代表阀门类型《蝶阀》 7——代表连接方式《对夹》 1——代表结构形式《中线》 X——代表阀座材质《橡胶》 -代表分隔键 16——代表公称压力《1.6MPA》 Q——代表阀体材料《…

【测试转型】人工智能的当下,测试团队如何敏捷转型 —— 无测试组织

文章目录 〇、引子一、什么是“无测试组织”?二、无测试组织适用于哪些场景?三、无测试组织还有哪些优势或特点?新书推荐 —— 《**无测试组织:测试团队的敏捷转型** 》 〇、引子 初次看到“无测试组织”的朋友可能会觉得有标题党…

Apache ActiveMQ RCE漏洞复现(CNVD-2023-69477)

0x01 产品简介 ActiveMQ是一个开源的消息代理和集成模式服务器,它支持Java消息服务(JMS) API。它是Apache Software Foundation下的一个项目,用于实现消息中间件,帮助不同的应用程序或系统之间进行通信。 0x02 漏洞概述 Apache ActiveMQ 中存…

Spring Boot集成Swagger接口分类与各元素排序问题

在上一篇中我们完成使用JSR-303校验,以及利用Swagger2得到相关接口文档,这节,我们在原先的基础之上,完成Swagger中关于对各个元素之间控制前后顺序的具体配置方法。 Swagger的接口的分组 首先我们需要对Swagger中的接口也就是以…

【LeetCode】102. 二叉树的层序遍历

题目链接 文章目录 Python3方法一: 广度优先搜索 (BFS) ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法二: 深度优先搜索 (DFS) ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯ C方法一: 广度优先搜索 (BFS) ⟮ O ( n ) ⟯ \lgroup O(n…

Android stdio 无法新建或打开AIDL文件(解决方法)

1.在gradle文件中添加如下代码 2.AIDL要求minsdk>16,并且要使aidl true(在Gradle中添加) android{ buildFeatures { aidl true } } 我们看见,可以创建AIDL文件了 3.接着,我们看到文件出现如下提示 4.在gradle…

hypercube背景设置为白色,绘制高光谱3D立方体

import scipy pip install wxpython PyOpenGL和Spectral需要本地安装 可参考链接https://blog.csdn.net/qq_43204333/article/details/119837870 参考:https://blog.csdn.net/Tiandailan/article/details/132719745?spm1001.2014.3001.5506Mouse Functions:left-cl…
最新文章