Node.js链接MySql

前言:

        在现代 Web 开发和后端服务中,Node.js 因其高性能和异步特性被广泛使用。MySQL 作为流行的关系型数据库之一,提供了稳定高效的数据存储和管理能力。将 Node.js 与 MySQL 结合,可以构建强大的数据驱动型应用。

一、环境准备

安装必要依赖

npm install express mysql cors jsonwebtoken body-parser

数据库准备

        创建一个名为 demo 的数据库,并添加 user 表: 

CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL,`password` varchar(100) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、核心代码实现

数据库连接配置 (dbconfig.js)

const mysql = require('mysql');// 建立连接池
const pool = mysql.createPool({host: 'localhost',user: 'root',password: 'root',database: 'demo',
})/*** 执行SQL查询的Promise封装* @param {string} sql SQL语句* @param {array} values 参数值* @returns {Promise} 查询结果*/
const query = (sql, values) => {return new Promise((resolve, reject) => {pool.getConnection((err, connection) => {if (err) {console.log('数据库连接错误', err)reject(err)return}connection.query(sql, values, (err, rows) => {if (err) {console.log('SQL执行错误', err)reject(err)return}resolve(rows)connection.release() // 释放连接回连接池})})})
}module.exports = query;

   关键点说明:

  • 使用链接池提高数据库性能,方便后期的统一管理。
  • Promise 封装使异步操作更易管理。 

Express 服务器配置 (server.js)

const express = require('express')
const query = require('./utils/dbconfig')
const cors = require('cors')
const jwt = require('jsonwebtoken')
const bodyParser = require('body-parser')const app = express()
const PORT = 3000;// 安全配置
const JWT_SECRET = 'your-secret-key-here'; // 生产环境应使用环境变量// CORS跨域配置
const corsOptions = {origin: ['http://localhost:5173'], // 允许的前端地址methods: ['GET', 'POST', 'OPTIONS'],allowedHeaders: ['Content-Type', 'Authorization']
}// 中间件
app.use(cors(corsOptions))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))// 启动服务器
app.listen(PORT, () => {console.log(`Server is running on port ${PORT}`)
})

        到这里基本的配置就完成了,现在就可以去完成接口的实现了。

接口实现

登录接口:

app.post('/login', async (req, res) => {try {const { username, password } = req.body;// 参数验证 对请求体中的username和password进行非空检查if (!username || !password) {return res.status(400).json({success: false,message: '用户名和密码不能为空'});}// 数据库查询验证 使用预处理SQL语句查询匹配的用户const sql = 'SELECT * FROM user WHERE username = ? AND password = ?';const users = await query(sql, [username, password]);if (users.length === 0) {return res.status(401).json({success: false,message: '用户名或密码错误'});}const user = users[0];// 使用jsonwebtoken生成访问令牌const token = jwt.sign({ userId: user.id, username: user.username },JWT_SECRET,{ expiresIn: '1h' } // Token有效期1小时);// 返回成功响应res.json({success: true,message: '登录成功',token: token,user: {id: user.id,username: user.username}});} catch (err) {console.error('登录错误:', err);res.status(500).json({success: false,message: '服务器错误'});}
});

         使用Express框架处理POST请求。主要功能包括参数验证、数据库查询、JWT生成和错误处理。

        这边其实在实际项目中像密码这类敏感数据为了安全应该使用哈希存储而非明文查询。

const sql = 'SELECT * FROM user WHERE username = ?';
const users = await query(sql, [username]);
const isValid = await bcrypt.compare(password, users[0].password_hash);
验证:

        到这里就可以来验证我们完成的接口了,这里可以给大家推荐一个VScode中的插件:

        可以看到接口是可以正常运行的,并返回了一个token给我们,这边我写了一个vue的例子,包含了 Vue Router 和  axios的二次封装,这些我在之前的博客都详细的讲过,可以点击对应的文章查看我之前的博客。

        我做了一个简单的登录页面:

<template><div class="login"><h1>Login</h1><form><label for="username">Username:</label><input type="text" id="username" v-model="username"><label for="password">Password:</label><input type="password" id="password" v-model="password"><button type="button" @click="login">Login</button></form></div>
</template><script setup>
import { ref } from 'vue';
import router from '../router';const username = ref('');
const password = ref('');function login() {
}
</script>

axios封装:

// 1.引入axios
import axios from "axios";// 2.创建axios对象
const service = axios.create({baseURL: 'http://localhost:3000'
});// 3.设置请求拦截器 请求前进行一些操作 比如添加请求头、设置loading动画等
service.interceptors.request.use(config => {// 在请求头中添加tokenconst token = localStorage.getItem('token');if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;
}, err => {Promise.reject(error)
})// 4.设置响应拦截器 后端给前端返回数据 可以处理http状态码
service.interceptors.response.use((response) => {if (response.status === 200) {return response.data}},error => {if (error.response) {switch (error.response.status) {case 401:// 处理未授权console.log('请检查账号密码')breakcase 403:// 处理禁止访问console.log('禁止访问')breakcase 404:// 处理未找到console.log('未找到')breakcase 500:// 处理服务器错误console.log('服务器错误')break}}throw error}
)export default service

 模块化:

import request from '../request';// 登录
export function getLogin(userName,password){return request({url: '/login',method: 'post',data: {username: userName,password: password}})
}

        这样我们直接调用这个函数就能发送请求了。 

        在登录页面中导入对应的函数并使用:

import { getLogin } from '../utils/api/users';function login() {getLogin(username.value, password.value).then(res => {if(res.success){// 将token存入localStoragelocalStorage.setItem('token', res.token);// 跳转到首页router.push('/');}}).catch(err => {throw err;});
}

        在路由中配置路由守卫来防止url跳转:

// 配置路由守卫
router.beforeEach((to, from, next) => {const token = localStorage.getItem('token')const isAuthenticated = !!token// 如果路由需要认证但用户未登录if (to.meta.requiresAuth && !isAuthenticated) {return next('/login')}// 如果路由要求未登录(如登录页)但用户已登录if (to.meta.requiresGuest && isAuthenticated) {return next('/home') // 重定向到首页}// 其他情况正常放行next()
})

        这样基本的登录功能就完成了

Token 验证中间件

        在一些请求中需要携带token,否则无法请求到数据,就可以封装一个token验证中间件。

function authenticateToken(req, res, next) {const authHeader = req.headers['authorization'];const token = authHeader && authHeader.split(' ')[1]; // 提取Bearer Tokenif (!token) {return res.status(401).json({success: false,message: '未提供认证Token'});}// 验证Token有效性jwt.verify(token, JWT_SECRET, (err, user) => {if (err) {return res.status(403).json({success: false,message: '无效的Token'});}req.user = user; // 将用户信息附加到请求对象next(); // 继续后续处理});
}

获取用户列表

app.get('/users', authenticateToken, async (req, res) => {try {// 只返回必要字段,不包含密码const sql = 'SELECT id, username FROM user';const users = await query(sql)res.json({success: true,data: users})} catch (err) {console.error('Database error:', err);res.status(500).json({success: false,message: '获取用户列表失败'});}
})

        获取用户列表时就需要在请求头中添加token,在axios的二次封装中,在请求拦截器中就可以在请求头中统一添加token。

service.interceptors.request.use(config => {// 在请求头中添加tokenconst token = localStorage.getItem('token');if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;
}, err => {Promise.reject(error)
})

 模块化:

export function getUsers() {return request({url: '/users',})
}

三、安全最佳实践

  1. 密码存储:实际项目中应使用bcrypt等库进行哈希处理
  2.  环境变量:敏感信息(如数据库密码、JWT密钥)应存储在环境变量中
  3. HTTPS:生产环境必须启用HTTPS
  4. SQL注入防护:始终使用参数化查询
  5. Token安全:设置合理的过期时间,考虑实现刷新Token机制

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

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

相关文章

Charles 的 Windows proxy 对爬取瑞数6 网站接口数据的作用分析

其实本文还是源于上个月的这篇文章 ➡️▼ 耗时两天半&#xff0c;利用 DrissionPage绕过瑞数6&#xff0c;爬取某药*局数据经历~ 不同点是&#xff0c;当时爬取的是列表页&#xff08;已爬完&#xff09;&#xff0c;后面爬取的是详情页&#xff01;懂的都懂&#xff0c;差别还…

PHP 测验

PHP 测验 引言 PHP 作为一种流行的开源服务器端脚本语言,被广泛应用于网页开发、服务器端编程等领域。为了帮助大家更好地理解和掌握 PHP,我们特此推出本 PHP 测验。通过以下问题,您可以检验自己的 PHP 知识水平,同时也能了解自己在哪些方面需要加强。 测验内容 问题一…

阶段1--Linux中的文件服务器(FTP、NAS、SSH)

目录 一、FTP Server 1.1.简介 1.2.FTP基础 1.2.1.控制端口 1.2.2.数据端口 1.3.FTP Server默认配置 1.3.1.安装vsftp 1.3.2.准备分发的文件 1.3.3.启动服务 1.3.4.关闭防火墙 1.4.FTP Client&#xff08;默认仅能下载文件&#xff09; 1.4.1.LinuxFTP客户端程序1&#xff1a;l…

SpringBoot与Vue实战:高效开发秘籍

Spring Boot 是什么? Spring Boot 简介 Spring Boot 是基于 Spring 框架的快速开发工具,旨在简化 Spring 应用的初始搭建和开发过程。它通过约定大于配置的原则,提供自动配置、内嵌服务器和依赖管理等功能,使开发者能够快速构建独立运行的、生产级别的应用。 核心特点 …

基于 fastapi 的 YOLO 批量目标检测 API:支持单图 / 文件夹自适应处理

项目背景 在计算机视觉任务中&#xff0c;我们经常需要对大量图片进行目标检测和标注。YOLO 系列模型凭借其高效性成为目标检测的首选工具之一&#xff0c;但批量处理图片时往往需要编写繁琐的脚本。本文将介绍一个基于 Flask 和 YOLOv11 的 API 服务&#xff0c;支持单张图片…

周志华《机器学习导论》第13章 半监督学习

目录 1. 未标记样本 2. 生成式方法 高斯混合EM 3. 半监督SVM 存在未标记样本的SVM变形 4. 图半监督学习 对图权值迭代矩阵计算 5. 基于分歧的方法 多视图协同训练 6. 半监督聚类 k-means的条件变形 6.1 Constrained k-means 利用“必连”与 “勿连”约束 6.2 Constra…

消息推送功能设计指南:精准触达与用户体验的平衡之道

消息推送功能设计指南&#xff1a;精准触达与用户体验的平衡之道消息推送是平台与用户保持连接的重要桥梁&#xff0c;既能及时传递重要资讯&#xff0c;又能唤醒沉睡用户、提升活跃度。然而&#xff0c;推送功能若设计不当&#xff0c;可能变成 “信息骚扰”&#xff0c;导致用…

CanOpen--SDO 数据帧分析

CanOpen--SDO 数据帧分析1 介绍1.1 概述1.2 主站与从站2 数据帧详细分析2.1 主站发送的请求帧 (Client → Server)2.2 从站响应的确认帧 (Server → Client)成功数据帧内容示例错误帧2.3 命令字2.4 小端格式&#xff1a;低字节在前3 其他示例60FF index 发送 数值 1000 数据帧分…

Day20-二叉树基础知识

二叉树&#xff08;Binary Tree&#xff09;是一种每个节点最多有两个子节点的树形数据结构&#xff0c;这两个子节点分别称为左子节点和右子节点。二叉树是计算机科学中最基础、最常用的树结构之一&#xff0c;广泛应用于搜索、排序、表达式解析等领域&#xff01; 核心特点 …

示波器探头接口类型与PINTECH品致探头选型指南

一、示波器探头接口类型及技术特点1. BNC接口&#xff1a;通用型主流标准- 优势&#xff1a;75%以上示波器标配接口&#xff0c;具备阻抗匹配灵活&#xff08;50Ω/1MΩ&#xff09;、插拔稳定、抗干扰性强等特点。 - 应用场景&#xff1a;适用于大多数示波器&#xff08;如Le…

Spring之【Bean工厂后置处理器】

目录 BeanFactoryPostProcessor BeanDefinitionRegistryPostProcessor 使用一下Bean工厂后置处理器 定义包扫描范围 定义一个组件Bean 定义一个普通的类 自定义一个组件类实现Bean工厂后处理器 测试类 BeanFactoryPostProcessor 该接口是Spring提供的扩展点之一是一个…

【C++】第十八节—一文万字详解 | map和set的使用

嗨&#xff0c;我是云边有个稻草人&#xff0c;与你分享C领域专业知识(*^▽^*) 《C》本篇文章所属专栏—持续更新中—欢迎订阅— 目录 一、序列式容器和关联式容器 二、set系列的使用 2.1 set和multiset参考⽂档 2.2 set类的介绍 2.3 set的构造和迭代器 2.4 set的增删查…

Java 大视界 -- Java 大数据在智能交通自动驾驶车辆与周边环境信息融合与决策中的应用(357)

Java 大视界 -- Java 大数据在智能交通自动驾驶车辆与周边环境信息融合与决策中的应用&#xff08;357&#xff09;引言&#xff1a;正文&#xff1a;一、Java 构建的环境信息融合架构1.1 多传感器数据实时关联1.2 动态障碍物轨迹预测二、Java 驱动的决策系统设计2.1 紧急决策与…

单细胞转录组学+空间转录组的整合及思路

一、概念 首先还是老规矩&#xff0c;处理一下概念问题&#xff0c;好将之后的问题进行分类和区分 单细胞转录组&#xff1a;指在单个细胞水平上对转录组&#xff08;即细胞内所有转录出来的 RNA&#xff0c;主要是 mRNA&#xff09;进行研究的学科或技术方向&#xff0c;核心…

用Python实现神经网络(五)

这一节告诉你如何用TensorFlow实现全连接网络。安装 DeepChem这一节&#xff0c;你将使用DeepChem 机器学习工具链进行实验在网上可以找到 DeepChem详细安装指导。Tox21 Dataset作为我们的建模案例研究&#xff0c;我们使用化学数据库。毒理学家很感兴趣于用机器学习来预测化学…

ReasonFlux:基于思维模板与分层强化学习的高效推理新范式

“以结构化知识压缩搜索空间&#xff0c;让轻量模型实现超越尺度的推理性能” ReasonFlux 是由普林斯顿大学与北京大学联合研发的创新框架&#xff08;2025年2月发布&#xff09;&#xff0c;通过 结构化思维模板 与 分层强化学习&#xff0c;显著提升大语言模型在复杂推理任务…

PHP与Web页面交互:从基础表单到AJAX实战

文章目录 PHP与Web页面交互:从基础到高级实践 1. 引言 2. 基础表单处理 2.1 HTML表单与PHP交互基础 2.2 GET与POST方法比较 3. 高级交互技术 3.1 AJAX与PHP交互 3.2 使用Fetch API进行现代AJAX交互 4. 文件上传处理 5. 安全性考量 5.1 常见安全威胁与防护 5.2 数据验证与过滤 …

OpenCV基本的图像处理

参考资料&#xff1a; 参考视频 视频参考资料:链接: https://pan.baidu.com/s/1_DJTOerxpu5_dSfd4ZNlAA 提取码: 8v2n 相关代码 概述&#xff1a; 因为本人是用于机器视觉的图像处理&#xff0c;所以只记录了OpenCV的形态学操作和图像平滑处理两部分 形态学操作&#xff1a;…

Git 与 GitHub 学习笔记

本文是一份全面的 Git 入门指南,涵盖了从环境配置、创建仓库到日常分支管理和与 GitHub 同步的全部核心操作。 Part 1: 初始配置 (一次性搞定) 在开始使用 Git 之前,需要先配置好你的电脑环境。(由于网络的原因,直接使用https的方式拉取仓库大概率是失败的,故使用ssh的方…

文件系统-文件存储空间管理

文件存储空间管理的核心是空闲块的组织、分配与回收&#xff0c;确保高效利用磁盘空间并快速响应文件操作&#xff08;创建、删除、扩展&#xff09;。以下是三种主流方法&#xff1a;1. 空闲表法&#xff08;连续分配&#xff09;原理&#xff1a;类似内存动态分区&#xff0c…