package com.zway.common.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
/**
* JWT校验工具类
* <ol>
* <li>iss: jwt签发者</li>
* <li>sub: jwt所面向的用户</li>
* <li>aud: 接收jwt的一方</li>
* <li>exp: jwt的过期时间,这个过期时间必须要大于签发时间</li>
* <li>nbf: 定义在什么时间之前,该jwt都是不可用的</li>
* <li>iat: jwt的签发时间</li>
* <li>jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击</li>
* </ol>
*/
public class JWTUtil {
/**
* JWT 加解密类型
*/
private static final SignatureAlgorithm JWT_ALG = SignatureAlgorithm.HS256;
/**
* JWT 生成密钥使用的密码
*/
private static final String JWT_RULE = "wjtree.xin";
/**
* JWT 添加至HTTP HEAD中的前缀
*/
private static final String JWT_SEPARATOR = "Bearer ";
private static final Integer duration = 60 * 60 * 1000;
/**
* 使用JWT默认方式,生成加解密密钥
*
* @param alg 加解密类型
* @return
*/
public static SecretKey generateKey(SignatureAlgorithm alg) {
return MacProvider.generateKey(alg);
}
/**
* 使用指定密钥生成规则,生成JWT加解密密钥
*
* @param alg 加解密类型
* @param rule 密钥生成规则
* @return
*/
public static SecretKey generateKey(SignatureAlgorithm alg, String rule) {
// 将密钥生成键转换为字节数组
byte[] bytes = Base64.decodeBase64(rule);
// 根据指定的加密方式,生成密钥
return new SecretKeySpec(bytes, alg.getJcaName());
}
/**
* 构建JWT
*
* @param username jwt 面向的用户
* @param userId jwt 唯一身份标识
* @return JWT字符串
*/
public static String buildJWT(String username, String userId) {
// 获取JWT字符串
Date date = new Date();
Date durationDate = new Date(date.getTime() + duration);
String compact = Jwts.builder()
.signWith(JWT_ALG, generateKey(JWT_ALG, JWT_RULE))
.setSubject(username)
.setId(userId)
.setIssuedAt(new Date())
.setExpiration(durationDate)
.compact();
// 在JWT字符串前添加"Bearer "字符串,用于加入"Authorization"请求头
//return JWT_SEPARATOR + compact;
return compact;
}
/**
* 构建JWT
*
* @param username jwt 面向的用户
* @param userId jwt 唯一身份标识
* @return JWT字符串
*/
public static String buildJWT(String username, String userId,Long duration) {
// 获取JWT字符串
Date date = new Date();
Date durationDate = new Date(date.getTime() + duration);
String compact = Jwts.builder()
.signWith(JWT_ALG, generateKey(JWT_ALG, JWT_RULE))
.setSubject(username)
.setId(userId)
.setIssuedAt(new Date())
.setExpiration(durationDate)
.compact();
// 在JWT字符串前添加"Bearer "字符串,用于加入"Authorization"请求头
//return JWT_SEPARATOR + compact;
return compact;
}
/**
* 解析JWT
*
* @param key jwt 加密密钥
* @param claimsJws jwt 内容文本
* @return {@link Jws}
* @throws Exception
*/
public static Jws<Claims> parseJWT(Key key, String claimsJws) {
// 移除 JWT 前的"Bearer "字符串
// claimsJws = StringUtils.substringAfter(claimsJws, JWT_SEPARATOR);
// 解析 JWT 字符串
return Jwts.parser().setSigningKey(key).parseClaimsJws(claimsJws);
}
/**
* 校验JWT
*
* @param claimsJws jwt 内容文本
* @return ture or false
*/
public static Boolean checkJWT(String claimsJws) {
boolean flag = false;
try {
SecretKey key = generateKey(JWT_ALG, JWT_RULE);
// 获取 JWT 的 payload 部分
flag = (parseJWT(key, claimsJws).getBody() != null);
} catch (Exception e) {
}
return flag;
}
/**
* 校验JWT
*
* @param key jwt 加密密钥
* @param claimsJws jwt 内容文本
* @param sub jwt 面向的用户
* @return ture or false
*/
public static Boolean checkJWT(Key key, String claimsJws, String sub) {
boolean flag = false;
try {
// 获取 JWT 的 payload 部分
Claims claims = parseJWT(key, claimsJws).getBody();
// 比对JWT中的 sub 字段
flag = claims.getSubject().equals(sub);
} catch (Exception e) {
}
return flag;
}
/**
* 校验JWT
*
* @param claimsJws jwt 内容文本
* @param sub jwt 面向的用户
* @return ture or false
*/
public static Boolean checkJWT(String claimsJws, String sub) {
return checkJWT(generateKey(JWT_ALG, JWT_RULE), claimsJws, sub);
}
public static Claims getClaims(String claimsJws) {
Claims claims = parseJWT(generateKey(JWT_ALG, JWT_RULE), claimsJws).getBody();
return claims;
}
}
浙公网安备 33010602011771号