Express + mysql2 + jwt 實現簡單的登錄鑒權

目前項目中使用Express 實現簡單API功能,需要提供一套登錄鑒權方案。

這邊是API側實現 相關路由的登錄鑒權。

大體思路:就是,登錄接口中通過jwt加密?token返回前端,前端其他接口把加密好的放入請求頭Authorization中。中間件通過請求頭解密 token獲取userId。成功后運行默認接口,失敗后返回特定狀態碼和錯誤信息。

一、jwt工具方法

路徑:src/utils/jwt.ts


import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';dotenv.config({path: `.env.${process.env.NODE_ENV || 'development'}`,override: true 
});const SECRET = process.env.APP_SECRET || '';export const generateToken = (userId: string) => {return jwt.sign({ userId }, SECRET, { expiresIn: '1h' });
};export const verifyToken = (token: string) => {return jwt.verify(token, SECRET) as { userId: string };
};

generateToken:是登錄使用 userId加密生成token的方法。

verifyToken:是中間件解密獲取userId的方法。

二、中間件處理

路徑:src/middlewares/auth.ts

import { Request, Response, NextFunction } from 'express';
import { verifyToken } from '../utils/jwt';export const authMiddleware = (req: Request, res: Response, next: NextFunction
) => {const authHeader = req.header('Authorization');if (!authHeader?.startsWith('Bearer ')) {res.status(401).json({ error: 'Invalid authorization format' });} else {const token = authHeader.split(' ')[1];  // 取第二部分if (!token) {res.status(401).json({ error: 'Access denied' });} else {try {const decoded = verifyToken(token);(req as any).userId = decoded.userId;next();} catch (err) {res.status(400).json({ error: 'Invalid token' });}}}
};

這里獲取userId后沒有做其他操作,優化思路可以在接口其他頭中獲取緩存的userId進行比對,判斷是否是當前登錄用戶。

三、登錄API實現

src/app.ts

import loginRouter from './routes/loginRoutes.js';
//其他代碼省略//路由
app.use('/api/login', loginRouter);

src/routes/loginRoutes.ts

import { Router } from 'express';
import loginController from '../controllers/loginController.js';const router = Router();router.post('/', loginController.login);export default router;

src/controllers/loginController.ts

import { Request, Response } from 'express';
import { generateToken } from '../utils/jwt';
import { LoginData } from '../types/login';
import { RowDataPacket } from 'mysql2';
import pool from '../config/db.js';class LoginController {public async login(req: Request, res: Response): Promise<void> {try {const { username, password } = req.body;const [rows] = await pool.query(`SELECT ...`);//sql部分省略const users = (rows as RowDataPacket[]).map((row:any) => ({... //轉換數據結構部分省略})) as LoginData[];//登錄成功后返回token 和user用戶信息。res.status(200).json({ token: (users[0]?.id ? generateToken(users[0]?.id) : ''), user: users[0] || null });} catch (err) {console.log(err);res.status(500).json({ error: 'Database error' });}}
}export default new LoginController();

這里錯誤處理和登錄不成功沒有處理,可以進行再次優化。

四、前端代碼處理

提交憑證后存儲Token至localStorage

// LoginComponent.js
const handleLogin = async (credentials) => {const { data } = await axios.post('/api/login', credentials);localStorage.setItem('jwtToken', data.token);// 后續跳轉邏輯
};

通過axios攔截器自動附加Token:

// apiClient.js
axios.interceptors.request.use(config => {const token = localStorage.getItem('jwtToken');if (token) config.headers.Authorization = `Bearer ${token}`;return config;
});

通過上述代碼就大致可以完成一個簡單的登錄鑒權的實現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90312.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90312.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90312.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ReAct (Reason and Act) OR 強化學習(Reinforcement Learning, RL)

這個問題觸及了現代AI智能體&#xff08;Agent&#xff09;構建的兩種核心思想。 簡單來說&#xff0c;ReAct 是一種“調用專家”的模式&#xff0c;而強化學習 (RL) 是一種“從零試錯”的模式。 為了讓你更清晰地理解&#xff0c;我們從一個生動的比喻開始&#xff0c;然后進行…

iTwinjs 4.10-4.11 更新

撤銷更改 目前&#xff0c;撤銷一個有缺陷的變更集的唯一方法是從 iModel Hub 中移除它&#xff0c;這可能會導致許多副作用&#xff08;無法撤銷&#xff09;。一個更好的方法是在時間線中撤銷變更集&#xff0c;并將其作為新的變更集引入。盡管這種方法仍然具有侵入性&#…

【CSS-15】深入理解CSS transition-duration:掌握過渡動畫的時長控制

在現代網頁設計中&#xff0c;平滑的過渡效果是提升用戶體驗的關鍵因素之一。CSS transitions 為我們提供了一種簡單而強大的方式來實現元素在不同狀態之間的平滑過渡&#xff0c;而 transition-duration 屬性則是控制這些過渡效果時長的核心工具。本文將全面探討 transition-d…

mysql-筆記

1. 安裝mysql # 使用brew安裝 brew install mysql# 查看是否安裝成功 mysql -V 相關文檔&#xff1a; mac&#xff1a;macOS下MySQL 8.0 安裝與配置教程 - KenTalk - 博客園 Linux安裝&#xff1a;linux安裝mysql客戶端_linux mysql 客戶端-CSDN博客 2. 啟動mysql 每次使…

Spring Boot啟動優化7板斧(延遲初始化、組件掃描精準打擊、JVM參數調優):砍掉70%啟動時間的魔鬼實踐

Spring Boot啟動優化7板斧&#xff1a;砍掉70%啟動時間的魔鬼實踐1. 延遲初始化&#xff1a;按需加載的智慧2. 組件掃描精準打擊&#xff1a;告別無差別掃描3. JVM參數調優&#xff1a;啟動加速的隱藏開關4. 自動配置瘦身&#xff1a;砍掉Spring Boot的"贅肉"5. 類加…

從0開始學習計算機視覺--Day08--卷積神經網絡

之前我們提到&#xff0c;神經網絡是通過全連接層對輸入做降維處理&#xff0c;將輸入的向量通過矩陣和激活函數進行降維&#xff0c;在神經元上輸出激活值。而卷積神經網絡中&#xff0c;用卷積層代替了全連接層。 不同的是&#xff0c;這里的輸入不再需要降維&#xff0c;而…

解決阿里云ubuntu內存溢出導致vps死機無法訪問 - 永久性增加ubuntu的swap空間 - 阿里云Linux實例內存溢出(OOM)問題修復方案

效果圖報錯通過對實例當前截屏的分析發現&#xff0c;實例因 Linux實例內存空間不足&#xff0c;導致操作系統出現內存溢出&#xff08;OOM&#xff09; 無法正常啟動。請您根據 Code&#xff1a;1684829582&#xff0c;在文檔中查詢該問題對應的修復方案&#xff0c;并通過VNC…

Serverless JManus: 企業生產級通用智能體運行時

作者&#xff1a;叢霄、陸龜 概述&#xff1a;本文介紹如何使用 JManus 框架構建通用智能體應用&#xff0c;部署并運行在 Serverless 運行時&#xff0c;構建企業級高可用智能體應用的實踐經驗。基于阿里云 Serverless 應用引擎SAE 運行穩定高可用的智能體應用&#xff0c; 基…

MySQL的數據目錄

導讀&#xff1a;根據前面的所學知識&#xff0c;我們知道了InnoDB存儲引擎存儲數據的數據結構、存儲過程&#xff0c;而被組織好的數據則被存儲在操作系統的磁盤上&#xff0c;當我們在對表數據進行增刪改查時&#xff0c;其實就是InnoDB存儲引擎與磁盤的交互。此外&#xff0…

Web前端開發: :has功能性偽類選擇器

:has功能性偽類選擇器::has() 是 CSS 中的一個功能性偽類選擇器&#xff0c;它允許開發者根據元素的后代元素、兄弟元素或后續元素的存在或狀態來選擇目標元素。它本質上是一個“父選擇器”或“關系選擇器”&#xff0c;解決了 CSS 長期以來無法根據子元素反向選擇父元素的痛點…

深度學習8(梯度下降算法改進2)

目錄 RMSProp 算法 Adam算法 學習率衰減 RMSProp 算法 RMSProp(Root Mean Square Prop)算法是在對梯度進行指數加權平均的基礎上&#xff0c;引入平方和平方根。 其中e是一個非常小的數&#xff0c;防止分母太小導致不穩定,當 dw 或 db 較大時&#xff0c;(du)2,(db)2會較大&…

JAVA面試寶典 -《網絡編程核心:NIO 與 Netty 線程模型詳解》

網絡編程核心&#xff1a;NIO 與 Netty 線程模型詳解 文章目錄網絡編程核心&#xff1a;NIO 與 Netty 線程模型詳解一、傳統 BIO 模型&#xff1a;排隊買奶茶的阻塞模式 &#x1f964;1.1 專業解釋1.2 簡單點比喻1.3 簡單示例二、NIO 模型&#xff1a;智能叫號餐廳系統 &#x…

藍橋杯 第十六屆(2025)真題思路復盤解析

本文以洛谷平臺所提供的題目描述及評測數據為基礎進行講解。 前言&#xff1a;這是本人的藍橋杯試卷&#xff0c;大概排省一前40%的位置&#xff0c;實際上這屆題目偏難&#xff0c;我沒有做出太多的有效得分。我把當時的思路和現在學習的思路都復盤進來&#xff0c;希望給大家…

蘭頓螞蟻路徑lua測試

蘭頓螞蟻local p0 local x,y,z0,7,0 local function add() local result,id Block:getBlockID(x,y,z)if id1 thenBlock:destroyBlock(x,y,z,false) pp90 elseBlock:setBlockAll(x,y,z,1,0) pp-90 end x,zx-math.floor(0.5math.sin(math.rad(p))),z-math.floor(0.5math.cos(m…

【Axure RP】什么是Axure?Axure可以用來做什么?

【Axure RP】什么是Axure&#xff1f;Axure可以用來做什么&#xff1f; 目錄【Axure RP】什么是Axure&#xff1f;Axure可以用來做什么&#xff1f;Axure RP簡介Axure RP 是什么&#xff1f;Axure RP核心功能和應用場景Axure RP簡介 Axure RP 是什么&#xff1f; Axure RP 是一…

Java項目:基于SSM框架實現的暢玩北海旅游網站管理系統【ssm+B/S架構+源碼+數據庫+畢業論文】

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本暢玩北海旅游網站就是在這樣的大環境下誕生&#xff0c;其可以幫助管理者在短時間內處理完畢龐大的數據信息…

NuxtJS中網絡請求模塊的封裝與最佳實戰

在網絡開發中&#xff0c;封裝一個簡潔、高效的網絡請求模塊對于項目的可維護性和擴展性至關重要。本文將詳細介紹如何在NuxtJS中封裝一個通用的網絡請求模塊&#xff0c;并結合最佳實踐來說明如何使用它來進行網絡請求。良好的代碼結構和封裝&#xff0c;不但結構清晰還能夠大…

云歸子批量混剪軟件批量剪輯軟件批量分割視頻更新記錄

www.yunguizi.com 優化顯卡硬件加速配置 ? 優化 2025年07月07日 版本 v1.1.6 優化顯卡硬件加速配置 修復了一些重要內容 &#x1f41b; 修復 2025年07月06日 版本 v1.1.6 修復了一些重要內容 重構讀寫機制 ? 優化 2025年07月06日 版本 v1.1.6 優化了一些重要內容&#xff1b;…

SpringBoot校園外賣服務系統設計與實現源碼

概述 基于SpringBoot開發的校園外賣服務系統&#xff0c;實現了從外賣管理到訂單處理的全流程數字化解決方案&#xff0c;包含外賣管理、訂單處理、用戶管理等全方位功能。 主要內容 核心功能模塊&#xff1a; ??個人信息管理??&#xff1a; 修改密碼個人信息修改 ??…

東軟8位MCU低功耗調試總結

簡介主控選用8位ES7P7021&#xff0c;應用于磁吸無線充電場景&#xff0c;有一個雙向C口&#xff08;IP5219&#xff09;&#xff0c;MCU控制電量燈顯示&#xff0c;通過IIC控制C口的降額&#xff0c;插入TYPE-C線之后有一個外部中斷信號&#xff0c;觸發MCU喚醒&#xff0c;開…