JWT内置对象生成及解析Token过程。

引入依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>

编写测试类,生成Token

 //生成token
    @Test    //Junit依赖
    public void createToken(){
        Calendar calendar = Calendar.getInstance();    
        calendar.add(Calendar.SECOND,90);    //设置过期时间为90秒
        
        HashMap<String, Object> map = new HashMap<>();
        map.put("alg","HS256");
        map.put("typ","JWT");
        //生成token令牌 使用JWT对象的静态方法create();
        String token = JWT.create()
                .withHeader(map)       //标头(header)
                .withClaim("username","xiao")   //有效负载(payload)
                .withClaim("userid",21)
                .withExpiresAt(calendar.getTime())      //过期时间
                .sign(Algorithm.HMAC256("token"));      //签名
        //输出令牌
        System.out.println(token);
    }

生成结果:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU4MzE0NzcsInVzZXJpZCI6MjEsInVzZXJuYW1lIjoieGlhbyJ9.jVGjjdW7_9D8m3FsNx1lStHuRbGdz3M9U8vhvZHgd_o

编写测试类,根据签名及令牌解析token

public void encode_Token() {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU4MzI2OTAsInVzZXJpZCI6MjEsInVzZXJuYW1lIjoieGlhbyJ9.Xybh20Y9b2Z3m9-XYEn3z8UwDmd8xccBRn5rZucXGfg";
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("token")).build();
        DecodedJWT verify = jwtVerifier.verify(token);
        Claim typ = verify.getHeaderClaim("typ");
        System.out.println("标头typ:" + typ);           // Header
        Claim username = verify.getClaim("username");
        System.out.println("claim username:" + username);     // payload
        Date expiresAt = verify.getExpiresAt();
        System.out.println("过期时间:" + expiresAt);      //expiresAt
    }

得到结果

标头typ:"JWT"
claim username:"xiao"
过期时间:Tue Nov 02 14:14:39 CST 2021

解析过程中会出现的报错问题

-TokenExpiredException: 令牌过期
-SignatureVerificationException: 签名错误导致异常。
-AlgorithmMismatchException:    签名算法不一致

同时我们也可以在导入的外部库中看到JWT官方列出的异常提示

编写工具类

利用我们已经写好的测试类进行token工具类的封装以便日后开发。

首先我们将两个测试类中的公共部分进行抽取,生成Token方法及解析token方法中会用到我们的令牌,我们将令牌提取让两个方法作用域中都能使用到我们的令牌。其次我们在测试方法中利用传递参数的形式向生成token及解析token的方法传递参数信息。

token生成方法:我们利用map向payload传递了多个claim(宣称)再利用foreach进行遍历添加,利用Calendar对象取的当前系统时间,calendar中的add方法在原有时间的基础上增加时间,Calendar.second(秒)为增加时间的类型,time则传递设置token的具体时间,可进行自定义。

Token根据令牌解析token的方法: 如果token检验成功则会返回一个对象,如果token校验失败,则会抛出异常。(JWT官方列出的异常提示

public class JWT_UTil {
    //令牌
    private static final String sign_token = "token" ;
    /**
     *生成token
     */
    public static String createToken(HashMap<String, String> map,Integer time) {

        Calendar calendar = Calendar.getInstance(); //获取当前时间。
        calendar.add(Calendar.SECOND, time);   //设置过期时间为

        //利用Jwt builder 设置payload,sign,expires
        JWTCreator.Builder builder = JWT.create();
        //payload
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        //expires || sign
        String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(sign_token));

        return token;
    }
    /**
     *验证token
     */
    public static DecodedJWT encode_Token(String token) {

        return JWT.require(Algorithm.HMAC256(sign_token)).build().verify(token);

    }
}

再来看测试结果

验证token成功则返回一个对象,失败则抛出异常,返回对象后我们即可取出来自token中payload中的claim。

最后修改:2021 年 11 月 02 日 03 : 09 PM