文章目录:
正文:
当今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);
}