JWT - 签发和验证 - java demo

夏嘉德
2023-12-01

引入依赖

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.14.0</version>
</dependency>

提供者 签发/验证

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.impl.PublicClaims;
import com.auth0.jwt.interfaces.Claim;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class ServerSide {
    // 密钥,服务端保存,用于加解密
    private static final String SECRET = "chuanbin.zhang";

    public static String createJwtToken() {
        // 定义header
        Map<String, Object> header = new HashMap<>();
        header.put(PublicClaims.TYPE, "JWT");
        header.put(PublicClaims.ALGORITHM, "HS256");

        // 定义payload
        Map<String, Object> payload = new HashMap<>();
        payload.put("name", "chuanbin.zhang");
        payload.put("age", 18);
        payload.put("hobby", new String[]{"eat", "sleep"});

        Calendar c = Calendar.getInstance();
        // 签发时间
        Date nowTime = c.getTime();
        c.add(Calendar.MINUTE, 5);
        // 过期时间(5分钟)
        Date expTime = c.getTime();

        return JWT.create().withHeader(header)
                .withJWTId("jti")               // jti jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
                .withIssuedAt(nowTime)          // iat jwt的签发时间
                .withAudience("aud")            // aud 接收jwt的一方
                .withNotBefore(nowTime)         // nbf 定义在什么时间之前,该jwt都是不可用的
                .withExpiresAt(expTime)         // exp jwt的过期时间,这个过期时间必须要大于签发时间
                .withSubject("sub")             // sub jwt所面向的用户
                .withIssuer("iss")              // iss jwt签发者
                .withPayload(payload)
                .sign(Algorithm.HMAC256(SECRET));
    }

    public static Map<String, Claim> verifyJwtToken(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        try {
            return verifier.verify(token).getClaims();
        } catch (JWTVerificationException e) {
            throw new RuntimeException("token验证失败!");
        }
    }
}

消费者 获取/使用

public class CustomerSide {
    public static void main(String[] args) {
        // 创建token
        String token = ServerSide.createJwtToken();
        System.out.println("token = " + token);

        // 验证token
        Map<String, Claim> stringClaimMap = ServerSide.verifyJwtToken(token);
        System.out.println("stringClaimMap = " + stringClaimMap);

        // 验证有问题的token
        String badToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" +
                ".eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ" +
                ".EK46mXLLXTFKZ2BYgkv2J8kDIud4PNAaMwp6IA0JWak";
        ServerSide.verifyJwtToken(badToken);;
    }
}

控制台输出结果

token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhdWQiLCJzdWIiOiJzdWIiLCJuYmYiOjE2MTQ4NzA2MDQsImlzcyI6ImlzcyIsIm5hbWUiOiJjaHVhbmJpbi56aGFuZyIsImV4cCI6MTYxNDg3MDkwNCwiaWF0IjoxNjE0ODcwNjA0LCJqdGkiOiJqdGkiLCJhZ2UiOjE4LCJob2JieSI6WyJlYXQiLCJzbGVlcCJdfQ.tuprcdZgk1eE3guMMld-XsKZtxzrrzmoD7ZD0mmOdc0
stringClaimMap = {sub="sub", iss="iss", aud="aud", nbf=1614870604, name="chuanbin.zhang", exp=1614870904, iat=1614870604, jti="jti", age=18, hobby=["eat","sleep"]}
Exception in thread "main" java.lang.RuntimeException: token验证失败!
	at com.zcb.jwt.demo.ServerSide.verifyJwtToken(ServerSide.java:53)
	at com.zcb.jwt.demo.CustomerSide.main(CustomerSide.java:21)

Process finished with exit code 1
 类似资料: