什么是 JWT?一文彻底搞懂 JSON Web Token(附 Spring Boot 实战)

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!

你是否经常听到这些词:

  • “我们用 JWT 做登录认证”
  • “前端把 token 放在 Authorization 头里”
  • “JWT 无状态,适合分布式系统”

但你真的理解 JWT 到底是什么?它怎么工作?和 Session 有什么区别? 吗?

今天我们就用 通俗语言 + 图解 + Spring Boot 代码实战,带你从零彻底搞懂 JWT!


🧩 一、一句话解释 JWT

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间安全地传递“声明”(claims)的紧凑、自包含令牌。

简单说:JWT 就是一个加密的字符串,里面包含了用户身份信息,服务器不用查数据库就能验证你是谁!


🔍 二、JWT 长什么样?

一个典型的 JWT 看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 

它由 三部分组成,用点 . 分隔

部分说明是否可读
Header(头部)算法 + 类型Base64 可解码
Payload(载荷)用户数据(如 ID、角色、过期时间)Base64 可解码
Signature(签名)用于验证令牌是否被篡改不可逆
注意:JWT 默认是 Base64 编码,不是加密!任何人都能解码看到内容!
🔒 安全靠的是 签名(Signature),防止内容被篡改。

📦 三、三部分详解(附解码示例)

1. Header(头部)

{ "alg": "HS256", "typ": "JWT" } 
  • alg:签名算法(如 HS25 sH A256、RS256)
  • typ:令牌类型,固定为 JWT

2. Payload(载荷)— 存放用户信息的地方!

{ "sub": "1234567890", // 主题(通常是用户ID) "name": "John Doe", "admin": true, "iat": 1516239022, // 签发时间(时间戳) "exp": 1516242622 // 过期时间(重要!) } 
⚠️ 不要在 Payload 里放敏感信息(如密码、手机号)! 因为它是明文(Base64 可解码)!

3. Signature(签名)— 安全的核心!

服务器用 密钥 + 算法Header + Payload 进行签名:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey ) 
  • 客户端无法伪造签名(不知道 secretKey);
  • 服务器收到 JWT 后,会重新计算签名,比对是否一致;
  • 只要 Payload 被改,签名就失效!

🔄 四、JWT 认证流程(图解)

✅ 整个过程 服务器无需存储 session,真正“无状态”!

⚖️ 五、JWT vs Session(传统方案)

特性JWTSession
存储位置客户端(LocalStorage/Cookie)服务端(内存/Redis)
状态无状态(Stateless)有状态(需维护 session)
扩展性天然支持分布式需共享 session(如 Redis)
安全性依赖签名,防篡改依赖 session ID 随机性
登出难(需黑名单或短期过期)容易(删 session 即可)
传输大小较大(含用户数据)小(只传 session ID)
💡 JWT 适合:API 服务、微服务、移动端
💡 Session 适合:传统 Web 应用、需要强登出控制的系统

💻 六、Spring Boot 实战:手写 JWT 登录

1. 添加依赖

<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </attribute> <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> <version>0.11.5</version> <scope>runtime</scope> </dependency> 

2. JWT 工具类

@Component public class JwtUtil { private String secret = "MySecretKey123!@#"; // 生产环境应配置在 application.yml private long expiration = 86400000; // 24小时 public String generateToken(String userId) { return Jwts.builder() .setSubject(userId) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expiration)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public String getUserIdFromToken(String token) { return Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody() .getSubject(); } public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(secret).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } } 

3. 登录接口

@RestController public class AuthController { @Autowired private JwtUtil jwtUtil; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest req) { // 模拟验证账号密码(实际应查数据库) if ("admin".equals(req.getUsername()) && "123456".equals(req.getPassword())) { String token = jwtUtil.generateToken("10001"); return ResponseEntity.ok(Map.of("token", token)); } return ResponseEntity.status(401).body("账号或密码错误"); } } 

4. 拦截器:验证 JWT

public class JwtInterceptor implements HandlerInterceptor { @Autowired private JwtUtil jwtUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); if (jwtUtil.validateToken(token)) { // 可将用户ID存入 ThreadLocal 或 Request Attribute return true; } } response.setStatus(401); return false; } } 

注册拦截器:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JwtInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/login"); } } 

⚠️ 七、JWT 的致命缺点 & 注意事项

❌ 1. 无法主动登出(除非用黑名单)

  • JWT 一旦签发,在过期前一直有效;
  • 即使用户点击“退出”,旧 token 仍可使用;
  • 解决方案
    • 设置较短过期时间(如 15 分钟)+ 刷新令牌(Refresh Token);
    • 维护一个 Redis 黑名单,记录已登出的 token。

❌ 2. Payload 不是加密的!

  • 所有人都能解码看到内容;
  • 永远不要放密码、身份证号等敏感信息!

❌ 3. 密钥泄露 = 全盘崩溃

  • 如果 secretKey 泄露,攻击者可伪造任意用户 token;
  • 必须严格保管密钥!

✅ 最佳实践建议:

项目建议
过期时间Access Token 15~30 分钟,配合 Refresh Token
存储位置Web 用 HttpOnly Cookie(防 XSS),App 用安全存储
传输协议必须 HTTPS
密钥管理用配置中心或环境变量,不要硬编码

🎯 总结

  • JWT = Header + Payload + Signature
  • 自包含、无状态、适合分布式
  • 不是加密,而是签名防篡改
  • 无法主动登出是最大短板
  • Spring Boot 集成简单,但要注意安全细节

掌握 JWT,你就掌握了现代 API 认证的“通行证”!


视频看了几百小时还迷糊?关注我,几分钟让你秒懂!

Read more

保姆级实战:打通Web3开发全链路——整合Hardhat、Alchemy、MetaMask与Viem/Wagmi,在Sepolia测试网部署你的第一个智能合约

保姆级实战:打通Web3开发全链路——整合Hardhat、Alchemy、MetaMask与Viem/Wagmi,在Sepolia测试网部署你的第一个智能合约

在智能合约开发中,开发者常陷入“本地运行完美,上链立刻报错”的泥潭。公共 RPC 节点的速率限制(Rate Limiting)、状态不同步以及测试网水龙头(Faucet)的干涸,是阻碍 DApp 从 localhost 走向 testnet 的三大拦路虎。 本项目将构建一个稳健的部署流水线:通过集成 Alchemy 的 Supernode 基础设施,绕过公共节点的性能瓶颈,并利用 Hardhat 的配置变量管理系统保障私钥安全,最终实现一键将合约部署至 Sepolia 测试网并自动完成 Etherscan 验证。 作者自己构建的智能钱包合约 3. 技术架构与设计思路 (The "Why") 为什么选择 Hardhat + Alchemy + Sepolia 这个组合?这并非随意堆砌,而是基于当前以太坊生态现状的最优解。 1.

Whisper-large-v3内容创作工具:短视频配音自动识别+多语字幕同步

Whisper-large-v3内容创作工具:短视频配音自动识别+多语字幕同步 1. 项目概述:多语言语音识别新选择 如果你正在寻找一个能够自动识别视频配音、生成多语言字幕的工具,那么Whisper-large-v3就是你的理想选择。这个基于OpenAI Whisper Large v3模型构建的语音识别Web服务,支持99种语言的自动检测与转录,专门为内容创作者量身定制。 想象一下这样的场景:你有一段中文讲解的短视频,需要添加英文、日文、法文字幕。传统方法需要逐句翻译、手动打时间轴,耗时又费力。而使用Whisper-large-v3,只需上传音频文件,系统就能自动识别内容并生成准确的字幕文件,支持几乎全球所有主流语言。 这个工具由by113小贝团队二次开发构建,将原本需要复杂技术背景才能使用的语音识别模型,封装成了简单易用的Web服务。无论你是短视频创作者、教育工作者,还是企业培训师,都能快速上手使用。 2. 核心功能特点 2.1 多语言自动识别 Whisper-large-v3最强大的功能是支持99种语言的自动检测。你不需要事先告诉系统音频是什么语言,它能智能识别

【AIGC】AI工作流workflow实践:构建日报

【AIGC】AI工作流workflow实践:构建日报

workflow实践 * 引言 * 实现步骤分析 * 实践 * 创建 dify workflow 应用 * 创建工作流内部节点 * 1、设置输入字段 * 2、创建两个LLM节点 * 3、设置结束节点 * 运行工作流 * 结语 引言 工作流 workflow 是现在 LLM 很重要的一个概念,因为对于一个模型来说,非常复杂的问题很难一次性完美解决,而且可能需要很多别的辅助工具。而工作流就是将这些工具和模型组合起来,形成一个完整的解决方案。今天我们来做个工作流实践,帮助读者理解工作流。我们来构建一个帮助我们写日报的工作流。在帮助我们完成日报的填写的同时,我们需要它进行 AI 味的去除,免得出现别人一看就是 AI 写出来的文章的情况。 实现步骤分析 1. 我们需要一个可以构建工作流的平台,这边我们选择 dify 2. 我们需要模型根据我们提供的今天做的事情去自动生成日报 我们需要对刚才生成的文章进行 AI 味的去除 实践 创建

HTML编辑器集成AI写作?用Embedding模型打造智能输入

HTML编辑器集成AI写作?用Embedding模型打造智能输入 在内容创作日益高频的今天,从企业文案到个人博客,人们花在“如何表达得更好”上的时间越来越多。而与此同时,我们手里的工具却似乎停滞不前——大多数HTML编辑器仍然停留在“格式化文本”的层面,缺乏对语义的理解能力。 如果编辑器不仅能识别你写了什么,还能理解你想表达什么,并主动推荐更合适的说法、提醒重复内容、甚至帮你保持品牌语调一致呢? 这不再是科幻场景。借助Embedding模型与现代化大模型框架 ms-swift,我们完全可以在本地构建一个低延迟、高安全性的智能写作辅助系统,无缝嵌入任何基于浏览器的富文本编辑器中。 从“打字机”到“写作伙伴”:为什么需要语义感知的编辑器? 传统的文本匹配技术依赖关键词或正则规则,面对语言的多样性显得力不从心。比如用户输入“我们致力于可持续发展”,系统很难意识到这句话和“本公司坚持绿色发展理念”本质上是同义表达。 而现代Embedding模型通过将文本映射为高维向量,实现了真正的语义级相似性判断。哪怕两个句子用词完全不同,只要意思相近,它们在向量空间中的距离就会很近。 这种能