SpringBoot--JWT

一、JWT 的簡單了解

1. 什么是 JWT?

JWT(JSON Web Token)是一種開放標準(RFC 7519),用于在 各方之間安全地傳輸信息。它基于 JSON 格式,信息通過 數字簽名 的方式保證不可篡改,常用于 身份認證和信息交換


2. JWT 的結構

JWT 由三部分組成,每部分用 . 分隔:

Header.Payload.Signature

(1) Header(頭部)

描述 類型簽名算法。例如:

{"alg": "HS256","typ": "JWT"
}

Base64Url 編碼后得到第一部分。


(2) Payload(載荷)

存放 聲明(Claims) 的地方。
聲明分三類:

  • 注冊聲明(Registered Claims):建議但非必須使用的標準字段

    • iss:簽發者 (issuer)

    • sub:主題 (subject)

    • aud:接收者 (audience)

    • exp:過期時間 (expiration time)

    • nbf:生效時間 (not before)

    • iat:簽發時間 (issued at)

    • jti:JWT ID,用于防止重放攻擊

  • 公共聲明(Public Claims):大家約定好的字段

  • 私有聲明(Private Claims):系統內部定義的字段,比如 userIdrole

例如:

{"sub": "user123","name": "Alice","role": "admin","exp": 1692345600
}

Base64Url 編碼后得到第二部分。


(3) Signature(簽名)

用于防篡改。
計算方法:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret
)

即:把前兩部分拼接,用密鑰和算法加密生成簽名。


3. JWT 的認證流程

  1. 用戶登錄:客戶端提交用戶名、密碼。

  2. 服務端驗證:驗證通過后,生成 JWT(帶用戶信息、過期時間等),返回給客戶端。

  3. 客戶端存儲:通常存儲在 LocalStorage 或 Cookie 中。

  4. 后續請求:客戶端請求時在 Header 中帶上 Authorization: Bearer <token>

  5. 服務端驗證:服務端用密鑰驗證 JWT 是否有效、是否過期、是否被篡改。

  6. 驗證通過:允許訪問資源。


4. JWT 的優點

  • 無狀態:服務端不存儲 Session,支持分布式擴展。

  • 跨語言:JSON 格式,兼容性強。

  • 高性能:減少數據庫查詢,認證速度快。

  • 信息完整:載荷可攜帶用戶信息,減少額外查詢。


5. JWT 的缺點

  • 不可撤銷:一旦簽發,在過期前無法主動讓其失效(除非維護黑名單)。

  • 體積較大:比 Session ID 更大(因為要攜帶簽名和用戶信息)。

  • 安全風險:如果私鑰泄露,所有 token 都會失效。

? ?5.1 為什么說不可撤銷呢?在前端刪除jwt(前端銷毀)不就好了?

?????????用戶自己點擊 “退出登錄”,前端刪除 token,下次再訪問接口時就沒有 token 了 → 確實相當于退出了

?????????在大多數 正常用戶行為 下,這種方式足夠。

?5.1.1 但是會有特殊情況:

(1)多端登錄 / 被動下線🔹如果一個賬號在兩臺設備登錄,管理員希望強制其中一臺下線。🔹單靠前端刪 token,另一臺設備的 token 依然有效。(2)token 泄露🔹假如 token 被別人拷貝了(比如被竊取、抓包、XSS 攻擊),那個人依然可以繼續用。🔹你本地刪掉 token 沒用,因為“壞人”還有副本。(3)黑名單/封禁需求🔹如果公司后臺管理員封禁了某個賬號,這個用戶的 token 在過期前仍然能請求接口。🔹只能靠服務端來控制 token 的立即失效。

?? ?5.2 解決辦法:

????????具體實現本文不做演示,著重介紹JWT

  • 前端銷毀:保證用戶主動退出后,瀏覽器不再攜帶 token。

  • 后端控制:保證遇到異常場景(黑名單、泄露、多端沖突)時,能強制失效。

    • 方式一:Redis 黑名單

    • 方式二:Redis 白名單(只保留最新 token)

    • 方式三:短 token + refresh token


6. 使用場景

  • 用戶認證(替代傳統 session)。

  • API 鑒權(前后端分離、微服務)。

  • 信息安全傳輸(聲明不可篡改)。


二、Spring Boot 使用 JWT 的完整示例

這里我們用 jjwt 庫(io.jsonwebtoken:jjwt-api)來實現。


1. 添加依賴(Maven)

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- 支持 json 序列化 --><version>0.11.5</version><scope>runtime</scope>
</dependency>

2. 工具類 JwtUtil

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;import java.security.Key;
import java.util.Date;public class JwtUtil {// 私鑰(實際項目中放到配置文件里)private static final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);// 生成 tokenpublic static String generateToken(String userId, String role) {long nowMillis = System.currentTimeMillis();long expMillis = nowMillis + 3600000; // 1小時過期Date exp = new Date(expMillis);return Jwts.builder().setSubject(userId) // sub.claim("role", role) // 自定義字段.setIssuedAt(new Date(nowMillis)) // iat.setExpiration(exp) // exp.signWith(key) // 簽名.compact();}// 驗證 tokenpublic static boolean validateToken(String token) {try {Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);return true;} catch (JwtException e) {return false;}}// 獲取用戶IDpublic static String getUserId(String token) {Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();return claims.getSubject();}// 獲取角色public static String getUserRole(String token) {Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();return claims.get("role", String.class);}
}

3. Controller 示例

import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/auth")
public class AuthController {// 模擬登錄接口@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password) {// 假設用戶名=admin, 密碼=123456if ("admin".equals(username) && "123456".equals(password)) {// 登錄成功,生成 JWTreturn JwtUtil.generateToken("1001", "admin");}return "用戶名或密碼錯誤";}// 需要鑒權的接口@GetMapping("/check")public String check(@RequestHeader("Authorization") String token) {token = token.replace("Bearer ", "");if (JwtUtil.validateToken(token)) {return "用戶ID:" + JwtUtil.getUserId(token) +",角色:" + JwtUtil.getUserRole(token);}return "token 無效或已過期";}
}

4. 請求示例

(1) 登錄獲取 Token

POST http://localhost:8080/auth/login?username=admin&password=123456

返回:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDAxIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjkyMzQ1NjAwLCJleHAiOjE2OTIzNDkyMDB9.Tk7Q7jtwgm3d...

(2) 攜帶 Token 訪問接口

GET http://localhost:8080/auth/check
Header: Authorization: Bearer <上一步返回的token>

返回:

用戶ID:1001,角色:admin

? 總結:

  • JWT 由 頭部 + 載荷 + 簽名 組成。

  • 使用時,客戶端存儲 token 并在請求頭中傳遞。

  • Spring Boot 中可以通過 工具類 + 攔截器/過濾器 來實現鑒權。

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

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

相關文章

OpenTelemetry、Jaeger 與 Zipkin:分布式鏈路追蹤方案對比與實踐

OpenTelemetry、Jaeger 與 Zipkin&#xff1a;分布式鏈路追蹤方案對比與實踐 問題背景介紹 隨著微服務架構的普及&#xff0c;服務之間調用鏈路變得異常復雜&#xff0c;單一服務故障或性能瓶頸往往牽一發動全身。分布式鏈路追蹤&#xff08;Distributed Tracing&#xff09;能…

云原生俱樂部-RH124知識點總結(1)

RH124內容不是很多&#xff0c;但是也不知道多少能夠寫完&#xff0c;細節性的東西不會太多&#xff0c;但是確保每個都能夠有印象能理解。本來是打算一篇文章寫完的&#xff0c;但最后還是決定寫一個系列。至于RH124和RH134的內容為什么放在了k8s系列的后面&#xff0c;那只是…

Redis面試精講 Day 25:Redis實現分布式Session與購物車

【Redis面試精講 Day 25】Redis實現分布式Session與購物車 在高并發、多節點的現代Web應用架構中&#xff0c;傳統的本地Session存儲方式已無法滿足分布式系統的需求。如何實現跨服務、高可用、低延遲的用戶狀態管理&#xff0c;成為后端開發和面試中的高頻考點。今天是“Redi…

本地文件上傳到gitee倉庫的詳細步驟

本地文件上傳到gitee倉庫的詳細步驟 &#x1f530; 一、前期準備 注冊 Gitee 賬號 訪問 Gitee 官網完成注冊并登錄。 網址&#xff1a;https://gitee.com/ 安裝 Git 下載 Git 官方客戶端并完成安裝。 下載網址&#xff1a;https://git-scm.com/downloads 配置 Git 全局信息&…

7 索引的監控

1. 查看索引的監控狀態 GET /_cat/indices/log2?v&formatjson[{"health" : "yellow","status" : "open","index" : "log2","uuid" : "1OnzbVbJRn2grc5k198LlA","pri" : "…

【秋招筆試】2025.08.10米哈游秋招機考真題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍在線刷題 bishipass.com 米哈游 題目一:圖書館整理計劃 1??:貪心策略從左到右固定每個位置的最優元素 2??:使用線段樹維護區間最小值信息,支持單點更新和區間查詢 3??:每次選…

恒創科技:日本服務器 ping 不通?從排查到解決的實用指南

玩游戲、做跨境業務時&#xff0c;突然發現日本服務器 ping 不通&#xff0c;簡直能讓人瞬間焦慮 —— 這到底是網絡崩了&#xff0c;還是服務器出問題了?在本文中&#xff0c;我們將探討如何排除日本服務器 ping 請求故障&#xff0c;附帶常見原因及解決辦法。先搞清楚&#…

ThinkPHP的Controller獲取request對象的幾種方式

文章目錄環境在Controller中獲取Request對象構造器注入操作方法注入繼承BaseController助手函數Facade參考環境 Windows 11 專業版XAMPP 8.2.12 PHP 8.2.12VSCode 1.103.0 在Controller中獲取Request對象 要想在Controller中獲取Request對象&#xff0c;有以下幾種方式&…

week2-[循環結構]找出正數

week2-[循環結構]找出正數 題目描述 給定 NNN 個整數A1,A2,…,ANA_1,A_2,\ldots,A_NA1?,A2?,…,AN?。請求出這 NNN 個數中有多少個數是正數&#xff0c;并求出這些正數的平均值。如果 A1,A2,…,ANA_1,A_2,\ldots,A_NA1?,A2?,…,AN? 不存在正數&#xff0c;那么輸出 “Non…

Android平臺RTSP播放器選型指南:從開源方案到跨平臺低延遲專業SDK

1. 引言&#xff1a;Android RTSP 播放的三條路徑 在 Android 平臺實現 RTSP 播放&#xff0c;看似只是“能播起來”的問題&#xff0c;實際上是一個涉及延遲、穩定性、解碼性能、協議兼容、工程可控性等多維指標的綜合選型問題。 從安防監控、教育互動&#xff0c;到單兵指揮…

Linux安裝及遠程連接知識實踐

文章目錄一、VMware創建虛擬機故障及解決匯總1. 鏡像下載2. 鏡像選擇安裝3.安裝VMware遇到的相關問題4. VMware操作系統的安裝4.1 選擇系統的引導4.2 修改網卡名為eth0的形式(和CentOS7以前保持一致)4.3 進入下一步安裝界面4.4 進入到安裝摘要頁面(INSTALLATION SUMMARY)4.5 配…

F Core 批量寫與“軟實時”一致性:ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡

EF Core 批量寫與“軟實時”一致性&#xff1a;ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡 ? &#x1f4da; 目錄EF Core 批量寫與“軟實時”一致性&#xff1a;ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡 ?1. 術語與目標 &#x1f9ed;2. 技術選型總覽…

基于PSO粒子群多目標優化的微電網調度算法matlab仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序 4.系統原理簡介 4.1 改進粒子群算法 4.2 分布式電源與儲能模型公式 4.3 多目標函數 5.參考文獻 6.完整工程文件 1.課題概述 微電網優化調度的核心是在滿足系統約束&#xff08;如功率平衡、設備出力限制等&#xff09;的前…

Spring AI ChatClient集成Deepseek

Spring AI ChatClient集成Deepseek 下文將簡述如何通過spring ai集成deepseek實現智能對話。在開始之前你需要在deepseek官網申請一個apikey,并設置到系統變量中&#xff0c;保障安全性。 ChatModel 在集成deepseek前&#xff0c;我們先要了解一個chat model&#xff0c;chat m…

Azure微軟云內網接入問題

1. 域名解析失敗 azure需要給ClientSecretCredentialBuilder和AzureResourceManager都配置HTTP 代理,但還是會域名解析失敗,netty會調用InetAddress.getByName解析域名.最終只能在hosts文件寫死host和ip映射關系 2. netty版本不匹配,導致報錯netty某個方法找不到 azure只用引入…

【IDEA】設置Debug調試時調試器不進入特定類(Spring框架、Mybatis框架)

問題 以Ruoyi-Vue項目為例&#xff0c;以Debug方式啟動項目&#xff0c;在com.ruoyi.web.controller.system.SysUserController#list()方法中的userService.selectUserList(user)處打上斷點&#xff0c;訪問[系統管理–用戶管理]頁面&#xff0c;程序就會執行到該斷點處此時按下…

OpenCV 視頻處理全解析

OpenCV 視頻處理全解析&#xff1a;從基礎操作到高級應用?在計算機視覺領域&#xff0c;視頻處理是一個核心且廣泛應用的技術方向。無論是安防監控、自動駕駛還是短視頻特效&#xff0c;都離不開對動態視頻流的智能分析與處理。OpenCV 作為最流行的開源計算機視覺庫&#xff0…

java如何使用正則提取字符串中的內容

在Java中使用正則表達式提取字符串內容&#xff0c;主要通過java.util.regex包中的Pattern和Matcher類實現。以下是詳細步驟和示例&#xff1a;1. 基礎流程 import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexExample {public static void ma…

Baumer高防護相機如何通過YoloV8深度學習模型實現行人跌倒的檢測識別(C#代碼UI界面版)

《------往期經典推薦------》 AI應用軟件開發實戰專欄【鏈接】 序號項目名稱項目名稱11.工業相機 YOLOv8 實現人物檢測識別&#xff1a;&#xff08;C#代碼&#xff0c;UI界面版&#xff09;2.工業相機 YOLOv8 實現PCB的缺陷檢測&#xff1a;&#xff08;C#代碼&#xff0…

jetson orin nx(8G)燒錄super系統實錄

1. 說明 2. 下載新版發布包&#xff08;在PC上下載&#xff09; Jetson Linux Archive | NVIDIA Developer 安裝的jetpack版本為6.2.1&#xff08;rev.2)對應的Jetson Linux 36.4.4 點擊綠色區域的36.4.4>&#xff0c;進入下載頁面&#xff0c;如下 點擊Driver Package(B…