JWT基础使用简介

介绍了JSON Web Token的基础使用方式

JWT简介

JWTl定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。

组成:

第一部分:Header(头),记录令牌类型、签名算法等。 例如:{“alg”:“HS256”,“type”:“JWT”}

第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{“id”:“1”,“username”:“Tom”}

第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload融入,并加入指定秘钥,通过指定签名算法计算而来。

image-20250917212355991

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();
        }
    }
}

在官网再次验证

image-20250917210416802

本站于2025年3月26日建立
使用 Hugo 构建
主题 StackJimmy 设计