一、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…