1-4.Java JWT 之 jjwt 进阶(发行时间和过期时间、过期时间验证)
·
一、JWT 与 jjwt
1、JWT 与 jjwt 概述
-
JWT(JSON Web Token)通常用于身份验证和信息交换
-
JWT 提供了一种轻量级、自包含的方式来传递用户身份和其他相关信息,同时确保这些信息在传输过程中的安全性和完整性
-
jjwt 简单而强大的 Java 库,用于创建和验证 JWT,它提供了易于使用的 API,开发者可以轻松地生成和解析 JWT
2、jjwt 引入
- 在
pom.xml中引入相关依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.6</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
二、发行时间和过期时间
1、基本介绍
-
发行时间和过期时间用于验证 JWT 的有效性
-
在使用 jjwt 构建 JWT 时,setIssuedAt 方法和 setExpiration 方法分别用于设置发行时间和过期时间
-
不调用 setIssuedAt 方法和 setExpiration 方法,即不设置发行时间和过期时间,JWT 仍然可以被创建,但它将不包含 iat(
issued at,发行时间)和 exp(expiration time,过期时间)这两个标准声明
2、演示
准备密钥
private static String SECRET_KEY_STR;
static {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
SecretKey secretKey = keyGen.generateKey();
SECRET_KEY_STR = Base64.getEncoder().encodeToString(secretKey.getEncoded());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
(1)设置发行时间和过期时间
String jwt = Jwts.builder()
.setSubject("user123")
.setIssuer("MyIssuer")
.signWith(SignatureAlgorithm.HS256, SECRET_KEY_STR)
.compact();
System.out.println(jwt);
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY_STR)
.build()
.parseClaimsJws(jwt)
.getBody();
System.out.println("主题:" + claims.getSubject());
System.out.println("发行者:" + claims.getIssuer());
System.out.println("发行时间:" + claims.getIssuedAt());
System.out.println("过期时间:" + claims.getExpiration());
- 输出结果
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoiTXlJc3N1ZXIiLCJpYXQiOjE3MzQ5MzgyMjMsImV4cCI6MTczNDk0MTgyM30.eugoVdept39edcpLUAcQ3GGswynl6XgyFxt6qORIxj0
主题:user123
发行者:MyIssuer
发行时间:Mon Dec 23 15:17:03 CST 2024
过期时间:Mon Dec 23 16:17:03 CST 2024
(2)不设置发行时间和过期时间
String jwt = Jwts.builder()
.setSubject("user123")
.setIssuer("MyIssuer")
.signWith(SignatureAlgorithm.HS256, SECRET_KEY_STR)
.compact();
System.out.println(jwt);
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY_STR)
.build()
.parseClaimsJws(jwt)
.getBody();
System.out.println("主题:" + claims.getSubject());
System.out.println("发行者:" + claims.getIssuer());
System.out.println("发行时间:" + claims.getIssuedAt());
System.out.println("过期时间:" + claims.getExpiration());
- 输出结果
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoiTXlJc3N1ZXIifQ.GfZHZRocewWgBRqnolx9sSur9Op9xJVJWZSWWBwgvzY
主题:user123
发行者:MyIssuer
发行时间:null
过期时间:null
三、过期时间验证
1、基本介绍
-
对于未过期的 JWT,程序将正常解析
-
对于已过期的 JWT,程序将抛出 ExpiredJwtException 异常,建议在解析 JWT 时进行异常处理
2、演示
准备密钥
private static String SECRET_KEY_STR;
static {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
SecretKey secretKey = keyGen.generateKey();
SECRET_KEY_STR = Base64.getEncoder().encodeToString(secretKey.getEncoded());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
(1)解析未过期的 JWT
String jwt = Jwts.builder()
.setSubject("user123")
.setIssuer("MyIssuer")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY_STR)
.compact();
System.out.println(jwt);
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY_STR)
.build()
.parseClaimsJws(jwt)
.getBody();
System.out.println("主题:" + claims.getSubject());
System.out.println("发行者:" + claims.getIssuer());
System.out.println("发行时间:" + claims.getIssuedAt());
System.out.println("过期时间:" + claims.getExpiration());
- 输出结果
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoiTXlJc3N1ZXIiLCJpYXQiOjE3MzQ5Mzg4NTMsImV4cCI6MTczNDk0MjQ1M30.ZIGOKo22qbb4iYjOdHjYNcVmi_BtM7b1Kgp9ko7yYwY
主题:user123
发行者:MyIssuer
发行时间:Mon Dec 23 15:27:33 CST 2024
过期时间:Mon Dec 23 16:27:33 CST 2024
(2)解析已过期的 JWT
- 对于已过期的 JWT,程序将抛出 ExpiredJwtException 异常
String jwt = Jwts.builder()
.setSubject("user123")
.setIssuer("MyIssuer")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 5))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY_STR)
.compact();
System.out.println(jwt);
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY_STR)
.build()
.parseClaimsJws(jwt)
.getBody();
System.out.println("主题:" + claims.getSubject());
System.out.println("发行者:" + claims.getIssuer());
System.out.println("发行时间:" + claims.getIssuedAt());
System.out.println("过期时间:" + claims.getExpiration());
- 输出结果
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoiTXlJc3N1ZXIiLCJpYXQiOjE3MzQ5Mzg5MzQsImV4cCI6MTczNDkzODkzOX0.rMBwzQrWg8T58GSRupaVZpgySofXd-v5xHtmr4Hqpjs
io.jsonwebtoken.ExpiredJwtException: JWT expired 5967 milliseconds ago at 2024-12-23T07:28:59.000Z. Current time: 2024-12-23T07:29:04.967Z. Allowed clock skew: 0 milliseconds.
- 在解析 JWT 时进行异常处理
String jwt = Jwts.builder()
.setSubject("user123")
.setIssuer("MyIssuer")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 5))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY_STR)
.compact();
System.out.println(jwt);
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY_STR)
.build()
.parseClaimsJws(jwt)
.getBody();
System.out.println("主题:" + claims.getSubject());
System.out.println("发行者:" + claims.getIssuer());
System.out.println("发行时间:" + claims.getIssuedAt());
System.out.println("过期时间:" + claims.getExpiration());
} catch (ExpiredJwtException e) {
System.out.println("JWT 已过期");
} catch (SecurityException e) {
System.out.println("JWT 签名无效");
}
- 输出结果
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwiaXNzIjoiTXlJc3N1ZXIiLCJpYXQiOjE3MzQ5MzkwMTYsImV4cCI6MTczNDkzOTAyMX0.k85NlFxxk9pxpQj1b0NLEOTcIePzNjNcbk0ai-0_WX4
JWT 已过期
更多推荐


所有评论(0)