JWT简介
JWTl定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。
组成:
第一部分:Header(头),记录令牌类型、签名算法等。 例如:{“alg”:“HS256”,“type”:“JWT”}
第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{“id”:“1”,“username”:“Tom”}
第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload融入,并加入指定秘钥,通过指定签名算法计算而来。
JWT使用
引入依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!-- JJWT核心依赖 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- JJWT实现(必须包含) -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- JJWT JSON处理(使用Jackson,也可替换为其他JSON库) -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
|
截止2025.9.17为止的最新版
生成令牌与解析令牌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
public class Demo {
// 1. 生成符合 HS256 要求的密钥(256位)
private static final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
// 2. 将密钥转成 Base64 字符串(即 SECRET_KEY_STRING 的值)
private static final String SECRET_KEY_STRING = Base64.getEncoder().encodeToString(secretKey.getEncoded());
// 3. 从 Base64 字符串还原 SecretKey 对象
private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(SECRET_KEY_STRING.getBytes(StandardCharsets.UTF_8));
@Test
public void generateAndParseJwtTest() {
System.out.println("符合 HS256 要求的密钥:" + secretKey);
// 符合 HS256 要求的密钥:javax.crypto.spec.SecretKeySpec@1612026
System.out.println("使用的密钥(Base64编码): " + SECRET_KEY_STRING);
// 使用的密钥(Base64编码): LVVDX0Dmtqpb1629gMwxcnVYU1Apuy6xPP0imxSyCm0=
// 自定义数据
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("id", 1);
dataMap.put("username", "yuanyu");
// 第一步:生成令牌
String jwt = Jwts.builder()
.signWith(SECRET_KEY, SignatureAlgorithm.HS256) // 使用还原的密钥
.addClaims(dataMap) // 添加自定义信息
.setExpiration(new Date(System.currentTimeMillis() + Duration.ofHours(24).toMillis())) // 设置过期时间为24小时
.compact(); // 生成令牌
System.out.println("生成的令牌: " + jwt);
// 生成的令牌: eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ5dWFueXUiLCJleHAiOjE3NTgyMDAyMTl9.QN69cG3SMfu5RcZ7jmGOeAvTBMnS6qFdZQCY4Z7390M
// 第二步:立即使用相同密钥解析令牌(保证密钥绝对一致)
try {
Claims claims = Jwts.parserBuilder()
.setSigningKey(SECRET_KEY) // 使用还原的密钥
.build() // 构建解析器
.parseClaimsJws(jwt) // 解析令牌
.getBody(); // 获取载荷
System.out.println("解析成功,用户ID: " + claims.get("id"));
// 解析成功,用户ID: 1
System.out.println("解析成功,用户名: " + claims.get("username"));
// 解析成功,用户名: yuanyu
} catch (Exception e) {
System.err.println("解析失败: " + e.getMessage());
e.printStackTrace();
}
}
}
|
在官网再次验证
