Jwts用于创建和验证 ​​JSON Web Token(JWT)​​ 的开源库详解

Jwts用于创建和验证 ​​JSON Web Token(JWT)​​ 的开源库详解

在 Java 开发中,提到 Jwts 通常指的是 ​​JJWT(Java JWT)库​​中的核心工具类 io.jsonwebtoken.Jwts。JJWT 是一个专门用于创建和验证 ​​JSON Web Token(JWT)​​ 的开源库,而 Jwts 类是其提供的​​入口工具类​​,主要用于​​构建(签名)JWT​​ 和​​解析(验证并提取内容)JWT​​。

​Jwts 的核心作用​

Jwts 类的核心功能围绕 JWT 的​​生命周期​​展开,主要包括两大操作:

  1. ​构建并签名 JWT​​(生成 Token):将业务数据(声明)打包为 JWT,并通过密钥或私钥进行签名,确保 Token 不可篡改。
  2. ​解析并验证 JWT​​(解析 Token):验证 JWT 的签名有效性,并提取其中的声明(如用户信息、过期时间等)。

​一、构建并签名 JWT(生成 Token)​

通过 Jwts.builder() 方法创建一个 JWT 构建器(JwtBuilder),逐步设置 Token 的​​声明(Claims)​​和​​签名参数​​,最终生成签名的 JWT 字符串。

​关键步骤与方法​
  1. ​设置基础声明(必选)​​:
    JWT 规范定义了一些标准声明(Claims),Jwts 提供了便捷方法设置这些声明:

    • setIssuer(String iss):设置签发者(Issuer)。
    • setSubject(String sub):设置主题(Subject,通常是用户标识)。
    • setAudience(String aud):设置接收者(Audience)。
    • setExpiration(Date exp):设置过期时间(必选,Token 失效时间)。
    • setNotBefore(Date nbf):设置生效时间(可选,Token 在此时间前无效)。
    • setIssuedAt(Date iat):设置签发时间(默认当前时间,可选)。
  2. ​设置自定义声明(可选)​​:
    通过 claim(String name, Object value) 方法添加业务相关的自定义声明(如用户角色、权限等)。

  3. ​设置签名算法和密钥​​:
    通过 signWith(SignatureAlgorithm alg, Key key) 方法指定签名算法(如 HMAC SHA256、RSA 等)和对应的密钥(对称或非对称)。

​示例:生成 JWT​
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.util.Date;public class JwtGenerator {// 生成安全的密钥(仅示例,实际需妥善保管)private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);public static String generateToken(String userId, String role) {return Jwts.builder().setSubject(userId) // 主题(用户ID).claim("role", role) // 自定义声明:用户角色.setIssuedAt(new Date()) // 签发时间(默认当前时间).setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 过期时间(1小时后).signWith(SECRET_KEY) // 使用 HMAC-SHA256 算法签名,密钥为 SECRET_KEY.compact(); // 生成紧凑的 JWT 字符串}public static void main(String[] args) {String token = generateToken("user123", "admin");System.out.println("生成的 JWT: " + token);// 输出示例:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE2NTYzMjAwLCJleHAiOjE3MTY1NjY4MDB9.xxx...}
}

​二、解析并验证 JWT(提取内容)​

通过 Jwts.parserBuilder() 方法创建一个 JWT 解析器(JwtParserBuilder),设置验证参数(如密钥、算法),然后调用 parseClaimsJws(String jwt) 方法解析并验证 JWT。若验证通过,返回包含声明的 Claims 对象;若验证失败(如签名错误、已过期),则抛出异常。

​关键步骤与方法​
  1. ​设置验证密钥和算法​​:
    通过 setSigningKey(Key key) 方法设置签名验证的密钥(需与生成 Token 时的密钥一致)。
    若 Token 使用非对称算法(如 RSA),需设置公钥(setVerificationKey)。

  2. ​可选配置(如忽略过期时间)​​:
    通过 requireExpiration(false) 等方法调整验证策略(一般不建议忽略过期时间)。

  3. ​解析并验证​​:
    调用 parseClaimsJws(String jwt) 方法解析 Token,返回 Jws<Claims> 对象,通过 getBody() 获取声明(Claims)。

​示例:解析 JWT​
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.security.Keys;
import java.security.Key;public class JwtParser {private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 与生成时的密钥一致public static Claims parseToken(String token) {return Jwts.parserBuilder().setSigningKey(SECRET_KEY) // 设置验证密钥.build().parseClaimsJws(token) // 解析并验证 JWT.getBody(); // 获取声明内容}public static void main(String[] args) {String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE2NTYzMjAwLCJleHAiOjE3MTY1NjY4MDB9.xxx..."; // 假设是生成的合法 Tokentry {Claims claims = parseToken(token);System.out.println("用户ID: " + claims.getSubject()); // 输出:user123System.out.println("角色: " + claims.get("role")); // 输出:adminSystem.out.println("过期时间: " + claims.getExpiration()); // 输出:过期时间戳} catch (Exception e) {System.out.println("Token 解析失败: " + e.getMessage()); // 签名错误、过期等场景会抛异常}}
}

在 Java 的 JWT(JSON Web Token)处理库 ​​JJWT(Java JWT)​​ 中,Jwts 是一个核心工具类,主要用于​​构建(生成)JWT​​ 和​​解析(验证/读取)JWT​​。它本身是一个工厂类,提供静态方法返回 JwtBuilder(构建器)或 JwtParser(解析器)实例,实际功能由这些实例的方法实现。

三、核心方法分类

Jwts 的方法主要分为两类:​​构建 JWT​​ 和 ​​解析 JWT​​。

1. 构建 JWT(生成令牌)

通过 Jwts.builder() 获取 JwtBuilder 实例,用于设置 JWT 的声明(Claims)和签名,最终生成 JWT 字符串。

常用方法:
方法说明
Jwts.builder()工厂方法,返回一个 JwtBuilder 实例,用于开始构建 JWT。
JwtBuilder.setSubject(String subject)设置 JWT 的主题(sub 声明),通常为用户标识。
JwtBuilder.setIssuer(String issuer)设置 JWT 的颁发者(iss 声明)。
JwtBuilder.setAudience(String audience)设置 JWT 的接收者(aud 声明)。
JwtBuilder.setExpiration(Date expiration)设置 JWT 的过期时间(exp 声明,UTC 时间)。
JwtBuilder.setNotBefore(Date notBefore)设置 JWT 的生效时间(nbf 声明,UTC 时间)。
JwtBuilder.setId(String id)设置 JWT 的唯一标识(jti 声明),通常用于防重放攻击。
JwtBuilder.claim(String name, Object value)自定义声明(如 emailrole 等非标准声明)。
JwtBuilder.signWith(SignatureAlgorithm algorithm, Key key)指定签名算法(如 HS256RS256)和密钥(对称或非对称),完成签名。
2. 解析 JWT(验证与读取)

通过 Jwts.parser() 获取 JwtParser 实例,用于验证 JWT 的签名并解析其声明。

常用方法:
方法说明
Jwts.parser()工厂方法,返回一个 JwtParser 实例,用于开始解析 JWT。
JwtParser.setSigningKey(Key key)设置签名验证的密钥(对称或非对称),必须与生成 JWT 时的密钥一致。
JwtParser.requireIssuer(String issuer)强制验证 JWT 的颁发者(iss 声明)必须等于指定值(可选校验)。
JwtParser.requireAudience(String audience)强制验证 JWT 的接收者(aud 声明)必须等于指定值(可选校验)。
Jws<Claims> parseClaimsJws(String jwt)解析并验证 JWT(带 JWS 签名),返回 Jws<Claims> 对象(包含头部和声明)。
Claims parseClaimsJwt(String jwt)解析 JWT(不验证签名,仅当已手动验证过时使用,不安全!)。

四、示例代码

生成 JWT(构建)
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.util.Date;// 生成密钥(实际生产环境应安全存储)
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);String jws = Jwts.builder().setSubject("user123")                  // 主题.setIssuer("my-app")                    // 颁发者.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 1小时后过期.claim("role", "admin")                 // 自定义声明.signWith(key)                          // 签名(使用 HS256 算法和密钥).compact();                             // 生成 JWT 字符串
解析 JWT(验证与读取)
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.security.Key;Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 必须与生成时的密钥一致String jws = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwib3NfdXNlciI6Im15LWFwcCIsImV4cCI6MTY5MTYxNjAwMCwicm9sZSI6ImFkbWluIn0..."; // 实际 JWT// 解析并验证签名
var jwsClaims = Jwts.parser().setSigningKey(key).requireIssuer("my-app") // 强制验证颁发者.parseClaimsJws(jws);// 读取声明
String subject = jwsClaims.getBody().getSubject(); // "user123"
String role = jwsClaims.getBody().get("role", String.class); // "admin"
Date expiration = jwsClaims.getBody().getExpiration(); // 过期时间

五、注意事项

  1. ​版本差异​​:JJWT 0.11.x 及以上版本(支持 Java 8+)与旧版本(0.x 早期)API 略有不同(如 Key 类型从 byte[] 改为 java.security.Key),需根据版本调整代码。
  2. ​签名验证​​:解析 JWT 时必须调用 signWith()setSigningKey() 验证签名,否则无法保证令牌未被篡改。
  3. ​声明校验​​:推荐通过 requireIssuer()requireAudience() 等方法显式校验关键声明,避免使用未验证的令牌。
  4. ​密钥安全​​:对称算法(如 HS256)的密钥需严格保密;非对称算法(如 RS256)需妥善管理公私钥对。

​Jwts 支持的常见场景​

  • ​单点登录(SSO)​​:用户登录后生成 JWT,后续请求携带 JWT 完成身份验证。
  • ​接口鉴权​​:微服务间通过 JWT 传递用户权限信息,避免重复查询数据库。
  • ​无状态认证​​:服务端无需存储 Token,通过签名验证即可确认 Token 合法性。

​注意事项​

  1. ​密钥安全​​:签名密钥(尤其是对称算法的密钥)需严格保密,泄露会导致 Token 被伪造。
  2. ​算法选择​​:推荐使用安全的算法(如 HS256、RS256),避免使用已废弃的算法(如 HS384/HS512 需评估性能)。
  3. ​声明的时效性​​:必须设置 exp(过期时间),防止 Token 长期有效被劫持。
  4. ​敏感信息避免明文​​:JWT 内容仅 Base64 编码(可解码),不要存储密码等敏感信息。

​总结​

Jwts 是 JJWT 库的核心工具类,主要用于​​生成和解析 JWT​​:

  • ​生成 Token​​:通过 Jwts.builder() 设置声明和签名,生成签名的 JWT 字符串。
  • ​解析 Token​​:通过 Jwts.parserBuilder() 验证签名并提取声明,确保 Token 合法性和数据完整性。

合理使用 Jwts 可以高效实现无状态认证、跨服务鉴权等场景,是 Java 中处理 JWT 的首选工具。

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

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

相关文章

如果发送的数据和接受的数据不一致时,怎么办?

那ART4222这个板卡举例&#xff0c;我之间输入一个原始数据“6C532A14”&#xff0c;但是在选择偶校验时&#xff0c;接收的是“6C532B14”&#xff0c;我发送的码率&#xff08;运行速度&#xff09;是100000&#xff0c;但接受的不稳定&#xff0c;比如&#xff1b;“100100.…

ISCC认证:可持续生产的新标杆。ISCC如何更快认证

在全球可持续发展浪潮中&#xff0c;ISCC&#xff08;国际可持续与碳认证&#xff09;体系已成为企业绿色转型的重要工具。这一国际公认的认证系统覆盖农业、林业、废弃物处理等多个领域&#xff0c;通过严格的可持续性标准、供应链可追溯性要求和碳排放计算规范&#xff0c;建…

想对学习自动化测试的一些建议

Python接口自动化测试零基础入门到精通&#xff08;2025最新版&#xff09;接触了不少同行&#xff0c;由于他们之前一直做手工测试&#xff0c;现在很迫切希望做自动化测试&#xff0c;其中不乏工作5年以上的人。 本人从事软件自动化测试已经近5年&#xff0c;从server端到web…

电子电气架构 ---智能电动汽车嵌入式软件开发过程中的block点

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

createAsyncThunk

下面&#xff0c;我们来系统的梳理关于 Redux Toolkit 异步操作&#xff1a;createAsyncThunk 的基本知识点&#xff1a;一、createAsyncThunk 概述 1.1 为什么需要 createAsyncThunk 在 Redux 中处理异步操作&#xff08;如 API 调用&#xff09;时&#xff0c;传统方法需要手…

STM32F103C8T6 BC20模块NBIOT GPS北斗模块采集温湿度和经纬度发送到EMQX

云平台配置 访问下载页面&#xff1a;免费试用 EMQX Cloud 或 EMQX Enterprise | 下载 EMQX&#xff0c;根据需求选择对应版本下载。将下载的压缩包上传至服务器&#xff08;推荐存放于C盘根目录&#xff0c;便于后续操作&#xff09;&#xff0c;并解压至指定路径&#xff08…

YOLO11涨点优化:自研检测头, 新创新点(SC_C_11Detect)检测头结构创新,实现有效涨点

目标检测领域迎来重大突破!本文揭秘原创SC_C_11Detect检测头,通过空间-通道协同优化与11层深度结构,在YOLO系列上实现mAP最高提升5.7%,小目标检测精度暴涨9.3%!创新性结构设计+即插即用特性,为工业检测、自动驾驶等场景带来革命性提升! 一、传统检测头的三大痛点 在目…

OSCP 考试期间最新考试政策

根据 Offensive Security 官方最新考试政策&#xff08;2025 年 7 月&#xff09;&#xff0c;OSCP 考试期间禁止或严格限制以下工具与行为&#xff1a; 一、绝对禁止使用的工具/服务 类别举例说明商业/付费版本Metasploit Pro、Burp Suite Pro、Cobalt Strike、Canvas、Core …

如何基于MQ实现分布式事务

文章目录1.可靠消息最终一致性1.1 本地消息表1.1.1 本地消息表的优缺点1.消息堆积&#xff0c;扫表慢2.集中式扫表&#xff0c;会影响正常业务3.定时扫表的延迟问题1.1.2 本地消息表的代码实践1.表结构设计2.具体业务实现1.2 事务消息1.2.1 事务消息的三个阶段阶段1&#xff1a…

ARM学习(45)AXI协议总线学习

笔者来介绍一下ARM AMBA 总线中的AXI协议 1、简介 ARM 公司推出的AMBA 总线(Advanced Microcontroller Bus Architecture) ,目前已经推出到AMBA5版本。主要包括 APB:Advanced Peripheral Bus,针对外设 AHB:Advanced High-Performance Bus,高性能总线,支持64/128 位多管…

Visual C++与HGE游戏引擎:创建伪2.5D斜45度视角游戏

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本教程专注讲解如何结合Visual C和HGE游戏引擎构建一个斜45度视角的伪2.5D游戏世界。HGE提供了DirectX的接口&#xff0c;简化了图形和音频处理&#xff0c;使得开发者可以专注于游戏逻辑和视觉效果的实现。教程…

打造个人数字图书馆:LeaNote+cpolar如何成为你的私有化知识中枢?

文章目录前言1. 安装Docker2. Docker本地部署Leanote蚂蚁笔记3. 安装cpolar内网穿透4. 固定Leanote蚂蚁笔记公网地址前言 在信息爆炸的时代&#xff0c;如何系统管理知识资产并实现价值输出&#xff1f;蚂蚁笔记&#xff08;Leanote&#xff09;提供了一种全新解决方案。这款开…

[特殊字符]️ 整个键盘控制无人机系统框架

&#x1f3af; 五大核心模块详解1. &#x1f4e5; 输入处理模块keyboard_control_node ├── 功能&#xff1a;捕获键盘输入并转换为ROS消息 ├── 文件&#xff1a;keyboard_control.cpp ├── 输入&#xff1a;键盘按键 (W/A/S/D/R/F/Q/E/L/ESC) ├── 输出&#xff1a;g…

机器学习第三课之逻辑回归(三)LogisticRegression

目录 简介 1.下采样 2.过采样 简介 接上两篇篇博客最后&#xff0c;我们使用了K折交叉验证去寻找最合适的C值&#xff0c;提升模型召回率&#xff0c;对于选取C的最优值&#xff0c;我们就要把不同C值放到模型里面训练&#xff0c;然后用验证集去验证得到结果进行比较&#x…

1.Java语言有什么特点

1.Java语言有什么特点 1.面向对象编程&#xff0c;拥有封装&#xff0c;继承和多态的特性&#xff0c;所有可以很好的设计出低耦合的项目工程。 2.很好的可移植性&#xff0c;在Java中有java虚拟机&#xff08;JVM&#xff09;的支持&#xff0c;每写一个类都是.Class文件。J…

部署 Kibana 8.2.2 可视化管理 Elasticsearch 8.2.2 集群

✅ 适用版本&#xff1a;Elasticsearch 8.2.2 Kibana 8.2.2 一、环境准备 组件版本示例地址Elasticsearch8.2.2192.168.130.61:9200, 192.168.130.62:9200, 192.168.130.65:9200Kibana8.2.2部署在 192.168.130.651操作系统CentOS 7⚠️ 严格版本匹配&#xff1a;Kibana 8.2.2…

7.2 I/O接口 (答案见原书 P305)

第7章 输入/输出系统 7.1 I/O系统基本概念 (答案见原书 P301) & 7.2 I/O接口 (答案见原书 P305) 01. 在统一编址的方式下,区分存储单元和I/O设备是靠( A )。 题目原文 在统一编址的方式下,区分存储单元和I/O设备是靠( )。 A. 不同的地址码 B. 不同的地址线 C. 不同…

并发编程常用工具类(上):CountDownLatch 与 Semaphore 的协作应用

在 Java 并发编程领域&#xff0c;JDK 提供的工具类是简化多线程协作的重要武器。这些工具类基于 AQS&#xff08;AbstractQueuedSynchronizer&#xff09;框架实现&#xff0c;封装了复杂的同步逻辑&#xff0c;让开发者无需深入底层即可实现高效的线程协作。本文作为并发工具…

Go 工程化全景:从目录结构到生命周期的完整服务框架

今天天气很好, 正好手头有个小项目, 整理了一下中小项目标准化的痛点问题, 如下, 希望可以帮到大家. 一个成熟的 Go 项目不仅需要清晰的代码组织&#xff0c;还需要完善的生命周期管理。本文将详细讲解生产级 Go 服务的目录设计&#xff08;包含 model 等核心目录&#xff09;、…

【C++】2. 类和对象(上)

文章目录一、类的定义1、类定义格式2、访问限定符3、类域二、实例化1、实例化概念2、对象⼤⼩三、this指针四、C和C语⾔实现Stack对⽐一、类的定义 1、类定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{ }中为类的主体&#xff0c;注意类定义结束时…