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
英文地址,請注明出處:http://en.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…