Java JWT:token 生成和解析

Java 使用 jjwt,实现 token 生成和解析

https://github.com/jwtk/jjwt

依赖

<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> <!-- or jjwt-gson if Gson is preferred -->
    <version>0.12.6</version>
    <scope>runtime</scope>
</dependency>

哈希签名方式

package com.ioufev;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.*;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class Main {
    public static void main(String[] args) {

        // 使用固定密钥:使用固定的字符串生成 HMAC 密钥,方便在开发和测试时使用。
//        String secretKey = "r-k.Uv4D@rrX2aYiLOJJC-)!XBD=-#[^i,&vykXQYtU6p.pF4'xQ#GZ-4AS+ri)vhBEAyQFfpZ+";
//        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 根据物理地址哈希得到,服务每次重启都不一样。
        // 使用生成密钥:使用 HS512 算法生成对称密钥。每次生成的密钥不同,因为是基于系统资源(如物理地址)的哈希值。
        MacAlgorithm alg = Jwts.SIG.HS512; //or HS384 or HS256
        SecretKey key = alg.key().build();

        // 设置自定义声明::可选的自定义的声明,即设置到信息中的键值对
        Map<String, Object> inputClaims = new HashMap<>();
        inputClaims.put("name", "张三");

        // 签名方式或者加密方式,二选一
        String token = Jwts.builder()
                .issuer("auth-server") // 可选,令牌的发行者,在解析 JWT 时可以验证这个值来确保它是由预期的授权服务器签发的。
                .subject("李四")
                .claims(inputClaims)
                .audience().add("api-client").and() // 可选,令牌的受众, 在解析 JWT 时可以验证这个值,确保令牌是为特定的客户端或 API 生成的。
//                .notBefore(notBefore) // 可选,java.util.Date,不早于
                .issuedAt(new Date()) // 设置签发时间为当前时间。
                .expiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))  // 设置 JWT 的过期时间为 30 分钟后。
                .id(UUID.randomUUID().toString()) // 设置一个随机生成的唯一标识符。
                .signWith(key) // 签名方式
//                .encryptWith(key, Jwts.ENC.A256CBC_HS512) // 加密方式,使用 AES 对称加密方式对 JWT 进行加密。
                .compact(); // 生成 JWT 并压缩为一个字符串形式


        System.out.println(token);

        // 解析,对应的签名或者加密方式
        Claims claims = Jwts.parser()
                .verifyWith(key) // 指定用于验证的密钥
//                .decryptWith(key) // 加密方式,指定用于解密的密钥。
                .build()
                .parseSignedClaims(token) // 签名方式
//                .parseEncryptedClaims(token) // 加密方式,对 JWT 进行解密,并获取其声明部分。
                .getPayload(); // 获取解密后的声明(claims)内容。
        System.out.println(claims.getSubject());
        System.out.println(claims.get("name"));
    }
}

对称加密方式

package com.ioufev;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.*;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class Main {
    public static void main(String[] args) {

        // 使用固定密钥:使用固定的字符串生成 HMAC 密钥,方便在开发和测试时使用。
//        String secretKey = "r-k.Uv4D@rrX2aYiLOJJC-)!XBD=-#[^i,&vykXQYtU6p.pF4'xQ#GZ-4AS+ri)vhBEAyQFfpZ+";
//        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 根据物理地址哈希得到,服务每次重启都不一样。
        // 使用生成密钥:使用 HS512 算法生成对称密钥。每次生成的密钥不同,因为是基于系统资源(如物理地址)的哈希值。
        MacAlgorithm alg = Jwts.SIG.HS512; //or HS384 or HS256
        SecretKey key = alg.key().build();

        // 设置自定义声明::可选的自定义的声明,即设置到信息中的键值对
        Map<String, Object> inputClaims = new HashMap<>();
        inputClaims.put("name", "张三");

        // 签名方式或者加密方式,二选一
        String token = Jwts.builder()
                .issuer("auth-server") // 可选,令牌的发行者,在解析 JWT 时可以验证这个值来确保它是由预期的授权服务器签发的。
                .subject("李四")
                .claims(inputClaims)
                .audience().add("api-client").and() // 可选,令牌的受众, 在解析 JWT 时可以验证这个值,确保令牌是为特定的客户端或 API 生成的。
//                .notBefore(notBefore) // 可选,java.util.Date,不早于
                .issuedAt(new Date()) // 设置签发时间为当前时间。
                .expiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))  // 设置 JWT 的过期时间为 30 分钟后。
                .id(UUID.randomUUID().toString()) // 设置一个随机生成的唯一标识符。
//                .signWith(key) // 签名方式
                .encryptWith(key, Jwts.ENC.A256CBC_HS512) // 加密方式,使用 AES 对称加密方式对 JWT 进行加密。
                .compact(); // 生成 JWT 并压缩为一个字符串形式


        System.out.println(token);

        // 解析,对应的签名或者加密方式
        Claims claims = Jwts.parser()
                .verifyWith(key) // 指定用于验证的密钥
                .decryptWith(key) // 加密方式,指定用于解密的密钥。
                .build()
//                .parseSignedClaims(token) // 签名方式
                .parseEncryptedClaims(token) // 加密方式,对 JWT 进行解密,并获取其声明部分。
                .getPayload(); // 获取解密后的声明(claims)内容。
        System.out.println(claims.getSubject());
        System.out.println(claims.get("name"));
    }
}

posted @ 2024-09-19 10:55  ioufev  阅读(2581)  评论(0)    收藏  举报