Node学习笔记之使用Express框架开发接口

news2024/9/22 17:32:19

我们利用node+express+mysql开发接口,对数据库数据进行简单增、删、查改等操作。

工具

数据库可视化

接口测试工具Postman

1、初始化

我们这里利用node+express+mysql开发一个简单的书城商店API。后面会使用result API规范接口

1、创建项目

新建文件夹server 安装依赖

npm init -y

安装依赖express

npm i express

新建app.js作为入口文件创建服务器实例

// 导入 express 模块

const express = require('express')

// 创建 express 的服务器实例

const app = express()

// write your code here...
// 调用 app.listen 方法,指定端口号并启动web服务器

app.listen(8000, function () {
  console.log('server running at http://127.0.0.1:8000')
})

安装nodemon

npm i nodemon

2、配置跨域依赖

npm i cors

在app.js中导入并配置cors中间件:

// 导入 cors 中间件

const cors = require('cors')

// 将 cors 注册为全局中间件

app.use(cors())

3、配置解析表单数据的中间件

通过如下的代码,配置解析application/x-www-form-urlencoded格式的表单数据的中间 件:

app.use(express.urlencoded({ extended: false }))

4、初始化路由

  1. 在项目根目录中,新建 router 文件夹,用来存放所有的 路由 模块

路由模块中,只存放客户端的请求与处理函数之间的映射关系

  1. 在项目根目录中,新建 router_handler 文件夹,用来存放所有的 路由处理函数模块

路由处理函数模块中,专门负责存放每个路由对应的处理函数

例如:新建用户user路由模块

在入口文件中注册路由

访问接口(确保服务在运行),没有运行访问不了服务

2.项目初始化

我们需要在数据库进行存储数据,对数据进行操作,这里使用Mysql,后面改进会使用一个更好用的MongoDB

1.配置MySQL

npm i mysql

2.创建数据库book,并创建一个用户users表格

新建数据库

创建users表格

2.实现连接数据库功能

新建db文件夹在其创建index.js连接数据库

// 导入 mysql 模块

const mysql = require('mysql')

// 创建数据库连接对象

const db = mysql.createPool({
    host: '127.0.0.1',
    user: 'root',
    password: 'root',
    database: 'book',
})

// 向外共享 db 数据库连接对象

module.exports = db

3.实现注册功能

1.实现步骤

1. 检测表单数据是否合法

2. 检测用户名是否被占用

3. 对密码进行加密处理

4. 插入新用户

2.检测表单数据是否合法

1. 判断用户名和密码是否为空

// 接收表单数据

const userinfo = req.body

// 判断数据是否合法

if (!userinfo.username || !userinfo.password) {
  return res.send({ status: 1, message: '用户名或密码不能为空!' })
}

2 检测用户名是否被占用

1. 导入数据库操作模块:

const db=require('../db/index')
2. 定义 SQL 语句:

2.定义SQL语句

const sql=`select * from users where username=?`

3. 执行 SQL 语句并根据结果判断用户名是否被占用:

db.query(sql, [userinfo.username], function (err, results) {
  // 执行 SQL 语句失败

  if (err) {
    return res.send({ status: 1, message: err.message })
 }
  // 用户名被占用

  if (results.length > 0) {
    return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })
 }
  // TODO: 用户名可用,继续后续流程...

})

4.对密码进行加密处理

为了保证密码的安全性,不建议在数据库以明文的形式保存用户密码,推荐对密码进行加密 存储

在当前项目中,使用bcryptjs对用户密码进行加密,优点:

加密之后的密码,无法被逆向破解

同一明文密码多次加密,得到的加密结果各不相同,保证了安全性

npm i bcryptjs

在/router_handler/user.js中,导入bcryptjs:

const bcrypt=require('bcryptjs')

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

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

5.插入新用户

  1. 定义插入用户的 SQL 语句:
const sql='insert into users set ?'

调用db.query()执行 SQL 语句,插入新用户:

db.query(sql, { username: userinfo.username, password: userinfo.password }, function 
(err, results) {
  // 执行 SQL 语句失败

  if (err) return res.send({ status: 1, message: err.message })
  // SQL 语句执行成功,但影响行数不为 1

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

  res.send({ status: 0, message: '注册成功!' })
})

全部代码

/**
 * 在这里定义和用户相关的路由处理函数,供 /router/user.js 模块进行调用

 */
const db = require('../db/index')
const bcrypt = require('bcryptjs')

// 注册用户的处理函数

exports.regUser = (req, res) => {
    // 接收表单数据

    const userinfo = req.body

    // 判断数据是否合法

    if (!userinfo.username || !userinfo.password) {
        return res.send({ status: 1, message: '用户名或密码不能为空!' })
    }
    const sql = `select * from users where username=?`
    db.query(sql, [userinfo.username], function (err, results) {
        // 执行 SQL 语句失败

        if (err) {
            return res.send({ status: 1, message: err.message })
        }
        // 用户名被占用

        if (results.length > 0) {
            return res.send({ status: 1, message: '用户名被占用,请更换其他用户名!' })
        }
        // 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串

        userinfo.password = bcrypt.hashSync(userinfo.password, 10)
        const sql = 'insert into users set ?'
        db.query(sql, { username: userinfo.username, password: userinfo.password }, function
            (err, results) {
            // 执行 SQL 语句失败

            if (err) return res.send({ status: 1, message: err.message })
            // SQL 语句执行成功,但影响行数不为 1

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

            res.send({ status: 0, message: '注册成功!' })
        })



    })

}

// 登录的处理函数

exports.login = (req, res) => {
    res.send('login OK')
}

为了方便测试接口我们允许其他字段为空

一开始表里没有数据

我们去测试注册功能(一定要配置解析表单数据的中间件)

注册功能完成

4.实现登录功能

核心实现思路:调用bcrypt.compareSync(用户提交的密码, 数据库中的密码)方法比较密码是 否一致

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

 const userinfo = req.body
    const sql = `select * from users where username=?`
    db.query(sql, userinfo.username, function (err, results) {
        // 执行 SQL 语句失败

        if (err) return res.cc(err)
        // 执行 SQL 语句成功,但是查询到数据条数不等于 1

        if (results.length !== 1) return res.send('登录失败!')
        // TODO:判断用户输入的登录密码是否和数据库中的密码一致
        // 拿着用户输入的密码,和数据库中存储的密码进行对比

        const compareResult = bcrypt.compareSync(userinfo.password, results[0].password)

        // 如果对比的结果等于 false, 则证明用户输入的密码错误

        if (!compareResult) {
            return res.send('登录失败!')
        }
        return res.send('登录成功!')



    })

基础登录接口实现

5、认识JWT

6、实现数据库命令增删查改的封装

7、注册和登录功能的优化

3、个人用户的基础API的实现

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

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

相关文章

记:2023香山杯-Ez加密器-题目复现和学习记录““

文章目录 前言题目分析and调试过程完整exp 前言 前段时间的比赛,那会刚入门o(╥﹏╥)o都不会写,现在复现一下。 题目分析and调试过程 查壳nie 进入IDA,shiftF12查找下字符串看看,定位过去 先用N重命名一下函数,方便…

GPDB7-新特性-角色创建

GPDB7-新特性-角色创建 9月GPDB7发布了release版本,新增了很多新特性及性能改进,对GPDB用户带来福音。业务在调研GPDB6升级到GPDB7的过程中,生产环境会创建用户,利用这些用户进行迁移。但是出现问题了,竟然会报&#x…

如何使用Linux编写STM32程序并且烧录

前言 (1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动实习岗位,可C站直接私聊,或者邮件:zhangyixu02gmail.com,此消息至2025年1月1日前均有效 (2&#xff0…

Z41H-64C高压闸阀型号解析

Z41H-64C型号字母含义 Z41H-64C型号是德特森阀门常用的高压闸阀型号字母分别代表的意思是: Z——代表阀门类别《闸阀》 4——代表连接方式《法兰》 1——代表结构形式《明杆》 H——代表密封堆焊《硬质合金》 -《分隔键》 64——代表公称压力《6.4MPA》 C——代表阀体材…

RT-Thread 6. ENV增加组件(从服务器下载得到)

键入“Y”、或者空格选中 保存 保存之后,自动修改这个文件 退回到ENV界面,输入:pkgs --update 多了 如果用keil4编译的话,输入:scons --targetmdk4,重新生成keil4工程,双击“project.uvpro…

10-类加载器

类加载器 类与类加载器 判断类是否“相等” 任意一个类,都由加载它的类加载器和这个类本身一同确立其在 Java 虚拟机中的唯一性,每一个类加载器,都有一个独立的类名称空间。 因此,比较两个类是否“相等”,只有在这…

北邮22级信通院数电:Verilog-FPGA(6)第六周实验:全加器(关注我的uu们加群咯~)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 作者建群啦!!!欢…

【计网 P2P】计算机网络 P2P(Peer to Peer)详解:中科大郑烇老师笔记 (七)

目录 0 引言1 C/S 模式 VS P2P模式2 P2P 概述2.1 纯P2P架构2.2 非结构化P2P和结构化(DHT)P2P2.2.1 非结构化P2P2.2.1 结构化P2P 2.3 P2P需要解决的问题及解决方案2.3.1 集中式目录2.3.2 完全分布式2.3.3 混合体 🙋‍♂️ 作者:海码…

智能井盖监测系统功能,万宾科技传感器效果

智能井盖传感器的出现是高科技产品的更新换代,同时也是智慧城市建设中的需求。在智慧城市建设过程之中,高科技产品的应用数不胜数,智能井盖传感器的出现,解决了城市道路安全保护着城市地下生命线,改善着传统井盖带来的…

【Qt样式(qss)-5】qss局部渲染混乱,错乱,不生效的一种原因

前言: 之前写过一些关于qss的文章: 【Qt样式(qss)-1】手册小结(附例:软件深色模式)_深蓝色主题qss表-CSDN博客 【Qt样式(qss)-2】使用小结(软件换肤&#…

拆贡献+统计非法可能不统计非法贡献:ARC150D

https://atcoder.jp/contests/arc150/tasks/arc150_d 先拆贡献成每个点,然后就只需要考虑这条链上的情况了 我们现在要求的是: 在所有点选完之前,最后一个点被选了多少次 我们发现这很难做,但有个性质: 在所有点选…

国外创意二维码案例:利马博物馆的二维码艺术展!

今天我们要分享的品牌创意二维码案例来自国外一家博物馆。 2022年12月,位于秘鲁的利马艺术博物馆策划并展出了一场别开生面的艺术展。和以往的展览不同,这次展览的主角是一些艺术画作“雕刻”而成的二维码。 利马博物馆(The Lima Art Museum…

OPC UA:工业领域的“HTML”

OPC UA是工业自动化领域的一项重要的通信协议。它的特点是包括了信息模型构建方法。能够建立工业领域各种事物的信息模型。在工业自动化行业,OPCUA 类似互联网行业的HTTP协议和“HTML”语言。能够准确,可靠地描述复杂系统中各个元素,并且实现…

质数(素数)prime :只能被 1 和 它本身整除的自然数,不可再分,(三种方式求出质数)

从 2 开始,到这个数 减 1 结束为止, 都不能被这个数本身整除。例如:5 是否是质数 ? 那么 2,3,4,都不能被 5 整除 所以 5 是 质数判断 n 是否是质数? 2,3,4&…

Python基础入门例程12-NP12 格式化输出(二)

目录 描述 输入描述: 输出描述: 示例1 解答: 说明: 描述 牛牛、牛妹和牛可乐都是Nowcoder的用户,某天Nowcoder的管理员希望将他们的用户名以某种格式进行显示, 现在给定他们三个当中的某一个名字name…

No module named ‘cv2’ 解决方法

目录 解决方案1解决方案2 解决方案1 一般情况下的解决方案 在自己的虚拟环境里面安装就行 pip install opencv-python解决方案2 但是我遇到的情况没有这么简单,我使用了pip list | grep open 搜索含有open字样的opencv的包,结果显示已经安装了 我直接进入我的自定义的虚拟…

TCP链接为什么要必须要四次挥手,为什么链接三次握手即可?

为什么TCP链接要三次握手,四次挥手? 寄快递两个问题三次握手四次挥手 寄快递 背景:小王要寄快递,早上上班把快递放在门口,等上午快递员到门口拿到快递。 小王打电话给快递小哥告诉他取件码。 这个交互其实就是TCP 传输…

Python第三方库 - Flask(python web框架)

1 Flask 1.1 认识Flask Web Application Framework( Web 应用程序框架)或简单的 Web Framework( Web 框架)表示一个库和模块的集合,使 Web 应用程序开发人员能够编写应用程序,而不必担心协议,线…

理解OOMKilled

背景 今天部署es集群时,pod总是报OOMKilled,于是理解的于是进行了排查 参考文章:https://zhuanlan.zhihu.com/p/519430209?utm_id0 排查,从两方面入手 1.查看node,并通过kubectl describe node,pod所在…

【Java笔记+踩坑】设计模式——原型模式

导航: 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/黑马旅游/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码-CSDN博客​ 目录 零、经典的克隆羊问题(复制10只属性相同的羊) 一、传统方案&#xff1…