实用指南:JWT 全面解析与 Spring Boot 实战教程

news/2025/11/30 19:08:37/文章来源:https://www.cnblogs.com/tlnshuju/p/19289961

实用指南:JWT 全面解析与 Spring Boot 实战教程

2025-11-30 19:07  tlnshuju  阅读(0)  评论(0)    收藏  举报

JWT 全面解析与 Spring Boot 实战教程

一、JWT 简介

JWT(JSON Web Token) 是一种基于 JSON 的 轻量级无状态认证令牌,常用于前后端分离和微服务系统中。
它将用户身份信息和签名一起打包,可以被客户端保存并在后续请求中携带,从而实现无状态认证。

JWT 组成

JWT 由三部分组成,用点 . 分隔:

Header.Payload.Signature
  1. Header(头部)

    • 描述签名算法和令牌类型

    • 常见字段:

      {
      "alg": "HS256",
      "typ": "JWT"
      }
  2. Payload(载荷)

    • 存储声明(Claims),包括标准 Claims 和自定义 Claims

    • 标准 Claims:

      • iss(Issuer):签发人
      • sub(Subject):主题
      • aud(Audience):接收方
      • exp(Expiration Time):过期时间
      • nbf(Not Before):生效时间
      • iat(Issued At):签发时间
      • jti(JWT ID):唯一标识
    • 自定义 Claims:业务相关字段,如用户角色、ID、权限等

  3. Signature(签名)

    • 使用算法对 Header + Payload + Secret(或私钥)签名
    • 作用:防止数据被篡改

示例 Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiJ1c2VyMSIsImlhdCI6MTY5NzU0MzYwMCwiZXhwIjoxNjk3NTQ3MjAwfQ
.
s5E7nEJ-Tp8kYmIiwzS3i_fzIDz5gXybR5Z7dgh

可以 Base64 解码 Header 和 Payload,查看信息,但 Signature 保证了其不可伪造性。


二、JWT 工作原理

  1. 用户登录:用户提交用户名和密码

  2. 服务器验证:验证通过后生成 JWT

  3. 客户端存储 Token:通常存在 LocalStorage 或 Cookie

  4. 客户端请求接口:在请求头 Authorization: Bearer <token> 携带 Token

  5. 服务器验证 Token

    • 校验签名是否正确
    • 校验是否过期或未生效
  6. 响应结果:验证通过允许访问,失败返回 401/403

对比传统 Session:

特性SessionJWT
状态存储服务器保存客户端保存
扩展性受限于服务器高,可跨服务
跨域较复杂简单(HTTP Header 携带)
安全性需要保护 SessionID需要保护 Secret + HTTPS

三、JWT 的使用场景


四、JWT 优缺点分析

优点:

  • 无状态,无需服务器存储 session
  • 可跨域、跨服务使用
  • 可携带自定义信息,减少额外请求

缺点:

  • 无法主动失效(Token 被盗用无法立即作废)
  • Token 基于 Base64 编码,容易被解码(但不能伪造签名)
  • Token 体积较大,不适合存储大量信息

五、Java 中 JWT 实现

这里以 java-jwt(Auth0) 为例,也可选择 jjwt。

1. Maven 依赖

<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>

2. 生成 JWT

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
public class JwtUtils {
private static final String SECRET = "mySecretKey";
// 生成 JWT
public static String generateToken(String username, int userId) {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
return JWT.create()
.withIssuer("my-app")                       // 签发者
.withSubject(username)                       // 用户名
.withClaim("userId", userId)                // 自定义字段
.withClaim("role", "admin")                 // 用户角色
.withIssuedAt(new Date())                    // 签发时间
.withExpiresAt(new Date(System.currentTimeMillis() + 3600_000)) // 1小时过期
.sign(algorithm);
}
}

3600_000 表示 3600 秒 × 1000 毫秒 = 1 小时,下划线提高可读性。

3. 验证与解析 JWT

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
public class JwtVerify {
private static final String SECRET = "mySecretKey";
public static void verifyToken(String token) {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("my-app")
.build();
DecodedJWT jwt = verifier.verify(token);
System.out.println("用户名:" + jwt.getSubject());
System.out.println("用户ID:" + jwt.getClaim("userId").asInt());
System.out.println("角色:" + jwt.getClaim("role").asString());
System.out.println("过期时间:" + jwt.getExpiresAt());
}
}

六、Spring Boot 集成 JWT

1. 登录接口签发 Token

@RestController
@RequestMapping("/auth")
public class AuthController {
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// TODO: 验证用户名密码
return JwtUtils.generateToken(username, 123);
}
}

2. 拦截器/Filter 校验 Token

@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.setStatus(401);
return false;
}
try {
String token = authHeader.substring(7);
JwtVerify.verifyToken(token);
return true;
} catch (Exception e) {
response.setStatus(401);
return false;
}
}
}

可在 WebMvcConfigurer 中注册拦截器,设置忽略 /login, /register 等无需认证路径。


七、JWT 使用注意事项

  1. 密钥管理

    • 不要硬编码,建议从环境变量或配置中心读取
  2. 过期时间

    • Token 不宜永久有效,可结合 Refresh Token 延长会话
  3. 敏感信息

    • 不要存储密码或银行卡等敏感信息
  4. HTTPS 传输

    • 防止中间人攻击
  5. 可控失效机制

    • 可结合 Redis 黑名单实现强制登出
  6. 刷新机制

    • 过期前刷新 Token,保证用户体验

八、JWT 与 OAuth2、Session 的关系


九、扩展与优化实践

  1. JWT + Redis 黑名单:可实现强制 Token 作废
  2. RS256 公私钥签名:更安全,避免共享密钥
  3. 自定义 Claims:可放权限列表、角色、部门信息
  4. 数组 Claims:适合多角色或权限管理
.withArrayClaim("permissions", new String[]{"read","write","delete"});
  1. 调试与工具

    • jwt.io → 可以在线解码 Token

十、总结

  • JWT 是轻量级、无状态的认证机制
  • 前端携带 Token 访问接口,后端只需验证签名即可
  • 适合前后端分离、微服务、单点登录
  • 注意安全实践:密钥管理、过期时间、HTTPS、刷新机制
  • 在 Java / Spring Boot 中使用 java-jwt 或 jjwt 都非常方便

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/982128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度亮相 SREcon25:搜索稳定背后的秘密,微服务雪崩故障防范 - 指南

百度亮相 SREcon25:搜索稳定背后的秘密,微服务雪崩故障防范 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…

Attention is all you need论文学习

前置知识 注意力机制 注意力机制的核心思想来源于人类在感知外部信息时所展现出的选择性注意能力。在面对复杂信息或长序列时,人类不会平均地处理所有信息,而是有选择地关注其中对当前任务更关键的部分。 深度学习中…

loj 515 贪心只能过样例

DP 题。 设 \(f_{i ,j}\) 为前 \(i\) 个数能否凑出 \(j\),转移即为: \[f_{i ,j} \gets f_{i ,j} \ \operatorname{or}\ f_{i ,j - k^2} \left( a\le k \le b\right) \]时间复杂度为 \(\mathcal O(n^5)\)。 注意这个式…

从数据采集到智能诊断:阿尔泰科技实时高精度远距离管道状态监测全流程 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2D3DICL-I2PReg论文学习

公式解读 前情提要:什么是相机 相机是虚拟的,实际上,它是指一个数学模型,它定义了我们如何将三维空间的点映射到二维照片上,它包含外参和内参,其中: (1)外参是指你所站的位置t,和你的朝向R。这个描述了相机在…

Spring使用el表达式

Spring使用el表达式 0. 背景 在项目中需要一个可动态执表达式的功能.项目本身是基于Springboot,可直接使用Spring提供的核心模块Spring Expression Language(SpEL). 在测试前,需要了解一些基本前置条件整体可以按照jav…

《程序员修建之道:从小工到专家》阅读笔记2

《程序员修建之道:从小工到专家》阅读笔记2当正确的 mindset 确立后,我们需要更高级的方法论来应对软件固有的复杂性。《程序员修炼之道》在软件设计方面提供了许多历久弥新的智慧,这些原则帮助我们在刚性与柔性、当…

《程序员修建之道:从小工到专家》阅读笔记3

《程序员修建之道:从小工到专家》阅读笔记3在技术快速迭代的今天,程序员最宝贵的资产不是当前掌握的某个框架或语言,而是持续学习与知识管理的能力。《程序员修炼之道》将我们的职业素养视为需要精心管理的"知…

AipexBase怎么用?AI 原生BaaS平台一句话做后端开发 - 实践

AipexBase怎么用?AI 原生BaaS平台一句话做后端开发 - 实践2025-11-30 18:42 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !importan…

CCPC2025 重庆站游记

游记开场写了 A,听了一下队友的 BE。然后一个小时的时候会了 F,看还没队过就开始抢一血,但直到封榜前这个题过了三十多个队了还一直过不去。中间会了 J,感觉这个题没道理才过四个队,趁着队友写 M 的间隙写完了。封…

完整教程:Elasticsearch:分布式搜索引擎数据库

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

wsl基本使用以及使用过程中遇到的问题

使用 任务栏搜索框中输入“Ubuntu xx.xx”后,直接进入对应Linux系统问题 1.git clone失败 fatal: unable to access https://github.com/xxx/xxx.git/: GnuTLS recv error (-110): The TLS connection was non-proper…

人工智能之数据分析 Matplotlib:第五章 常见函数

人工智能之数据分析 Matplotlib:第五章 常见函数人工智能之数据分析 Matplotlib 第五章 常见函数@目录人工智能之数据分析 Matplotlib前言一、Matplotlib 图像处理三剑客:imread / imshow / imsave1. plt.imread() …

CTF基础介绍与入门讲解

什么是CTF夺旗赛 CTF(Capture The Flag,夺旗赛) 是一种流行的信息安全竞赛形式,起源于1996年的DEFCON大会。CTF竞赛通过解决各种网络安全相关的挑战,帮助参赛者提升技术能力,同时也为网络安全领域培养人才。 当然…

2025/11/29 今天上课所以没有自我学习

2025/11/29 今天上课所以没有自我学习今日没有学习新内容,把前两天的内容随笔写了一下

基于大数据的全国降水可视化分析预测框架

基于大数据的全国降水可视化分析预测框架pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "M…

Day7-20251130

Java标识符与数据类型摘要: Java标识符命名规则:必须以字母、$或_开头,后续可包含数字,区分大小写且不能使用关键字。虽然支持中文命名但不推荐。 数据类型分为基本类型和引用类型。基本类型包括:数值类型:byte(…

Java项目中最常用的6个设计模式

在 Java 项目开发中,以下 6 种设计模式因实用性强、应用场景广泛而被高频使用: 1. 单例模式(Singleton Pattern) 用途:确保一个类仅有一个实例,并提供全局访问点。场景:线程池、数据库连接池、配置类、日志工具…

记录容器云基于debian镜像的自由组合

当然很多镜像都是有着专用的功能,这也是docker的设计目标,但是有时候我们也想把docker当vps使用。 所以,就想基于debian的镜像自由发挥。。。第一步:基于 debian:12-slim 开启一个容器 关键要设置:挂载一个目录,…

IDEA中使用http协议

IDEA中使用http协议三、如何使用协议 3.1使用http协议 项目右键-》Git -》 repository -》 remote -》选择http协议的地址3.2 使用ssh协议 首先Git Bash或软件生成SSH秘钥 生成秘钥请参考 SSH公钥默认存储在账户的主目…