Java JWT加密、解密
维基框架 2024-09-12 15:05:02 阅读 80
介绍
JSON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于作为 JSON 对象在各方之间安全地传输信息。由于此信息已进行数字签名,因此可以对其进行验证和信任。可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。
1、引入包
<code>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>3.8.1</version>
</dependency>
2、签名算法
/**
* 签名算法
*/
private static final SignatureAlgorithm signatureAlgorithm;
3、静态实例化值
/**
* 静态默认值
*/
static {
signatureAlgorithm = SignatureAlgorithm.HS512;
}
4、加密
/**
* 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)
*
* @param map 参数
* @param base64Security 密钥
* @return 返回结果
*/
public static String createJwt(Map<String, Object> map, String base64Security) {
//添加构成JWT的参数
JwtBuilder builder = builderJwt(map, base64Security);
//生成JWT token
return builder.compact();
}
/**
* 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)
*
* @param map 参数
* @param base64Security 密钥
* @param expiration 过期时间
* @return 返回结果
*/
public static String createJwt(Map<String, Object> map, String base64Security, long expiration) {
//添加构成JWT的参数
JwtBuilder builder = builderJwt(map, base64Security);
builder.setExpiration(new Date(expiration));
//生成JWT
return builder.compact();
}
/**
* 构建 jwt
*
* @param map 值
* @param base64Security 密钥
* @return 返回结果
*/
private static JwtBuilder builderJwt(Map<String, Object> map, String base64Security) {
return Jwts.builder().setHeaderParam("typ", "JWT")
.setClaims(map)
//估计是第三段密钥
.signWith(signatureAlgorithm, base64Security.getBytes());
}
5、解密
/**
* 解密
*
* @param jsonWebToken token
* @param base64Security 密钥
* @return 返回结果
*/
public static Claims parseJwt(String jsonWebToken, String base64Security) {
try {
Claims claims = Jwts.parser()
.setSigningKey(base64Security.getBytes())
.parseClaimsJws(jsonWebToken).getBody();
return claims;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
6、检查token
/**
* 检查token
*
* @param jwtToken token
* @param base64Security base64安全性
* @param userAgent 用户代理
* @return 返回 redis token
* @throws Exception 异常信息
*/
public static String checkToken(String jwtToken, String base64Security, String userAgent) throws GlobalException {
String token;
try {
Claims claims = parseJwt(jwtToken, base64Security);
long effective = IntegerConsts.TWENTY_FOUR * IntegerConsts.SIXTY * IntegerConsts.SIXTY;
Long time = ConvertUtils.convertLong(claims.get(BusinessConsts.TIME));
if (time <= IntegerConsts.ZERO) {
time = ConvertUtils.convertLong(claims.get(BusinessConsts.EXP));
}
// 验证 token 是否过期
LocalDateTime localDateTime = LocalDateUtils.timestampToLocalDateTime(time)
.plusSeconds(effective);
if (LocalDateUtils.greater(localDateTime, LocalDateTime.now())) {
throw new GlobalException("token 过期!");
}
// 验证 token 签名
Object loginName = claims.get(BusinessConsts.USER_NAME);
if (StringUtils.isNullAndSpaceOrEmpty(loginName)) {
loginName = claims.get(BusinessConsts.LOGIN_NAME);
}
StringBuilder builder = new StringBuilder();
builder.append(String.format("loginName=%s&effective=%s&time=%s&userAgent=%s", loginName, effective, time, userAgent));
token = String.valueOf(claims.get(BusinessConsts.HEADER_TOKEN));
String tokenPassword = Md5Utils.getMd5(builder.toString());
if (!tokenPassword.equals(token)) {
throw new GlobalException("token 签名验证失败!");
}
} catch (Exception ex) {
String message = "token 验证失败!";
if (ex instanceof GlobalException) {
message = ex.getMessage();
}
throw new GlobalException(message);
}
// 返回结果
return token;
}
7、测试
public static void main(String[] args) {
// 生成 JWT token
Map<String, Object> map = new HashMap<>(IntegerConsts.FOUR);
map.put(BusinessConsts.LOGIN_NAME, "username");
long time = System.currentTimeMillis() / IntegerConsts.ONE_THOUSAND;
map.put(BusinessConsts.TIME, time);
map.put(BusinessConsts.USER_NAME, "username");
map.put(BusinessConsts.USER_TYPE, "userType");
map.put(BusinessConsts.DISPLAY_NAME, "displayName");
// 暂不需要该参数
String userAgent = StringUtils.Empty;
StringBuilder builder = new StringBuilder();
/**
* 加密 token 参数
*/
long EFFECTIVE = IntegerConsts.TWENTY_FOUR * IntegerConsts.SIXTY * IntegerConsts.SIXTY;
String TOKEN_ENCRYPTION = "loginName=%s&effective=%s&time=%s&userAgent=%s";
builder.append(String.format(TOKEN_ENCRYPTION,
"username", EFFECTIVE, time, userAgent));
String tokenValue = Md5Utils.getMd5(builder.toString());
map.put(BusinessConsts.HEADER_TOKEN, tokenValue);
//密钥
String key = "cdkj-framework-jwt";
String token = JwtUtils.createJwt(map, key, System.currentTimeMillis() + 10000);
try {
JwtUtils.checkToken(token, key, "");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("JWT加密的结果:" + token);
System.out.println("JWT解密的结果:" + parseJwt(token, key));
}
测试结果
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。