【Java工具类】Jwt高可用工具类,支持链式编程

文章目录:


正文:

        当今Jwt的使用面非常广泛,但市面上主流的Jwt依赖在创建或解析时代码编写十分繁琐,因此,下面为大家提供一个能够满足基本需求的Jwt工具类,来简化代码

一、相关依赖

 这里使用的是com.auth0提供的Jwt依赖

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.4.0</version>
</dependency>

二、上工具类代码

 (保留了一点点java-jwt原本的味道)

package...;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.netty.handler.codec.base64.Base64Encoder;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class JwtUtils {
    private JWTCreator.Builder jwtBuilder;
    private Map<String, Object> headers;
    
    public JwtUtils(JWTCreator.Builder jwtBuilder) {
        this.jwtBuilder = jwtBuilder;
    }
    
    
    /**
     * 设置过期时间
     *
     * @param time     时间
     * @param timeUnit 时间单位
     * @return JwtUtils 对象
     */
    public static JwtUtils createJwt(int time, TimeUnit timeUnit) {
        long seconds = timeUnit.toSeconds(time);
        Instant instant = LocalDateTime.now()
                                       .plusSeconds(seconds)
                                       .atZone(ZoneId.of("UTC"))
                                       .toInstant();
        return new JwtUtils(JWT.create().withExpiresAt(instant));
    }
    
    /**
     * 不设置过期时间 (不安全)
     *
     * @return JwtUtils 对象
     */
    @Deprecated
    public static JwtUtils createJwt() {
        return new JwtUtils(JWT.create());
    }
    
    /**
     * 签名
     *
     * @param secret 密钥
     * @return Jwt 字符串
     */
    public String sign(String secret) {
        try {
            this.jwtBuilder.withHeader(this.headers);
            return this.jwtBuilder.sign(Algorithm.HMAC256(secret));
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 验证Jwt是否安全?... 验证是否过期
     *
     * @param jwt    jwt 字符串
     * @param secret 密钥
     * @return 当没有设置TTL时, 返回值始终为false
     */
    public static boolean isSafe(String jwt, String secret) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwt);
            Instant instant = verify.getExpiresAtAsInstant();
            LocalDateTime jwtExpiresTime = instant.atZone(ZoneId.of("UTC")).toLocalDateTime();
            return !jwtExpiresTime.isBefore(LocalDateTime.now());
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 获取Jwt过期时间
     *
     * @param jwt    Jwt字符串
     * @param secret 密钥
     * @return LocalDateTime
     */
    public static LocalDateTime getExpiresTime(String jwt, String secret) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwt);
            Instant instant = verify.getExpiresAtAsInstant();
            return instant.atZone(ZoneId.of("UTC")).toLocalDateTime();
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取单个值
     *
     * @param jwt    Jwt 字符串
     * @param name   key 名
     * @param secret 密钥
     * @return Claim 对象
     */
    public static Claim getClaim(String jwt, String secret, String name) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwt);
            return verify.getClaim(name);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取DecodedJWT对象
     *
     * @param jwt    jwt
     * @param secret 密钥
     * @return DecodedJWT对象
     */
    public static DecodedJWT getDecoded(String jwt, String secret) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwt);
            return verify;
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取头信息,并转为JSON
     *
     * @param jwt    jwt
     * @param secret 密钥
     * @return JSON
     */
    public static String getHeaderJson(String jwt, String secret) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(jwt);
            String encodedHeader = verify.getHeader();
            byte[] decodedHeader = Base64.getDecoder().decode(encodedHeader);
            return new String(decodedHeader);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取单个值
     *
     * @param jwt  Jwt 字符串
     * @param name key 名
     * @return Claim 对象
     */
    public static Claim getClaim(String jwt, String name) {
        try {
            DecodedJWT decode = JWT.decode(jwt);
            return decode.getClaim(name);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取DecodedJWT对象
     *
     * @param jwt jwt
     * @return DecodedJWT对象
     */
    public static DecodedJWT getDecoded(String jwt) {
        try {
            return JWT.decode(jwt);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取头信息,并转为JSON
     *
     * @param jwt jwt
     * @return JSON
     */
    public static String getHeaderJson(String jwt) {
        try {
            DecodedJWT decode = JWT.decode(jwt);
            String encodedHeader = decode.getHeader();
            byte[] decodedHeader = Base64.getDecoder().decode(encodedHeader);
            return new String(decodedHeader);
        } catch (Exception e) {
            return null;
        }
    }
    
    public JwtUtils setAuthor(String name) {
        this.jwtBuilder = this.jwtBuilder.withIssuer(name);
        return this;
    }
    
    public JwtUtils setKeyId(String keyId) {
        this.jwtBuilder = this.jwtBuilder.withKeyId(keyId);
        return this;
    }
    
    public JwtUtils addHeader(String name, Object object) {
        if (this.headers == null) {
            this.headers = new HashMap<>();
        }
        headers.put(name, object);
        return this;
    }
    
    public JwtUtils setHeader(Map<String, Object> headers) {
        this.headers = headers;
        return this;
    }
    
    public JwtUtils addClaim(String name, String string) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, string);
        return this;
    }
    
    public JwtUtils addClaim(String name, Integer integer) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, integer);
        return this;
    }
    
    public JwtUtils addClaim(String name, Long aLong) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, aLong);
        return this;
    }
    
    public JwtUtils addClaim(String name, Double aDouble) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, aDouble);
        return this;
    }
    
    public JwtUtils addClaim(String name, List list) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, list);
        return this;
    }
    
    public JwtUtils addClaim(String name, Map<String, Object> map) {
        this.jwtBuilder = this.jwtBuilder.withClaim(name, map);
        return this;
    }
    
    public JwtUtils addClaim(String name, String... strings) {
        this.jwtBuilder = this.jwtBuilder.withArrayClaim(name, strings);
        return this;
    }
    
    public JwtUtils addClaim(String name, Integer... integers) {
        this.jwtBuilder = this.jwtBuilder.withArrayClaim(name, integers);
        return this;
    }
    
    public JwtUtils addClaim(String name, Long... longs) {
        this.jwtBuilder = this.jwtBuilder.withArrayClaim(name, longs);
        return this;
    }
}

注:

        1. 时区只能是UTC不能更改! (因为Jwt依赖中内置的时区为UTC) 

        2. 根据HS256源码的描述,建议secret值(密钥)在256位以上


三、使用

@Test
void myTest() {
    String jwt = JwtUtils.createJwt(5, TimeUnit.MINUTES)
            .addClaim("hhh", "aaa", "bbb", "ccc")
            .addClaim("nnn", 114514)
            .sign("abc");
    
    if (JwtUtils.isSafe(jwt, "abc")) {
        Claim claim = JwtUtils.getClaim(jwt, "abc", "hhh");
        if (claim != null) {
            System.out.println(Arrays.toString(claim.asArray(String.class)));
        } else {
            System.out.println("claim为空");
        }
        
        Map<String, Claim> claimMap = JwtUtils.getAllClaim(jwt, "abc");
        if (claimMap != null) {
            System.out.println("nnn = " + claimMap.get("nnn").asInt());
        }
    }
    
    LocalDateTime expiresTime = JwtUtils.getExpiresTime(jwt, "abc");
    System.out.println(expiresTime);
}

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狐笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值