file/file-common/src/main/java/com/qiwenshare/common/util/JjwtUtil.java
2020-10-27 17:47:54 +08:00

94 lines
4.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.qiwenshare.common.util;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.net.util.Base64;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class JjwtUtil {
// jtijwt的唯一身份标识
public static final String JWT_ID = UUID.randomUUID().toString();
// 加密密文,私钥
public static final String JWT_SECRET = "jiamimiwen";
// 过期时间,单位毫秒
public static final int EXPIRE_TIME = 60 * 60 * 1000; // 一个小时
// public static final long EXPIRE_TIME = 7 * 24 * 3600 * 1000; // 一个星期
// 由字符串生成加密key
public static SecretKey generalKey() {
String secret = JWT_SECRET;
// 本地的密码解码
byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);
// 根据给定的字节数组使用AES加密算法构造一个密钥
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
// 创建jwt
public static String createJWT(String issuer, String audience, String subject) throws Exception {
// 设置头部信息
// Map<String, Object> header = new HashMap<String, Object>();
// header.put("typ", "JWT");
// header.put("alg", "HS256");
// 或
// 指定header那部分签名的时候使用的签名算法jjwt已经将这部分内容封装好了只有{"alg":"HS256"}
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 创建payload的私有声明根据特定的业务需要添加如果要拿这个做验证一般是需要和jwt的接收方提前沟通好验证的方式
Map<String, Object> claims = new HashMap<>();
claims.put("username", "admin");
claims.put("password", "010203");
// jti用户id例如20da39f8-b74e-4a9b-9a0f-a39f1f73fe64
String jwtId = JWT_ID;
// 生成JWT的时间
long nowTime = System.currentTimeMillis();
Date issuedAt = new Date(nowTime);
// 生成签名的时候使用的秘钥secret切记这个秘钥不能外露是你服务端的私钥在任何场景都不应该流露出去一旦客户端得知这个secret那就意味着客户端是可以自我签发jwt的
SecretKey key = generalKey();
// 为payload添加各种标准声明和私有声明
JwtBuilder builder = Jwts.builder() // 表示new一个JwtBuilder设置jwt的body
// .setHeader(header) // 设置头部信息
.setClaims(claims) // 如果有私有声明一定要先设置自己创建的这个私有声明这是给builder的claim赋值一旦写在标准的声明赋值之后就是覆盖了那些标准的声明
.setId(jwtId) // jti(JWT ID)jwt的唯一身份标识根据业务需要可以设置为一个不重复的值主要用来作为一次性token从而回避重放攻击
.setIssuedAt(issuedAt) // iat(issuedAt)jwt的签发时间
.setIssuer(issuer) // iss(issuer)jwt签发者
.setSubject(subject) // sub(subject)jwt所面向的用户放登录的用户名一个json格式的字符串可存放useridroldid之类作为用户的唯一标志
.signWith(signatureAlgorithm, key); // 设置签名,使用的是签名算法和签名使用的秘钥
// 设置过期时间
long expTime = EXPIRE_TIME;
if (expTime >= 0) {
long exp = nowTime + expTime;
builder.setExpiration(new Date(exp));
}
// 设置jwt接收者
if (audience == null || "".equals(audience)) {
builder.setAudience("Tom");
} else {
builder.setAudience(audience);
}
return builder.compact();
}
// 解密jwt
public static Claims parseJWT(String jwt) throws Exception {
SecretKey key = generalKey(); // 签名秘钥,和生成的签名的秘钥一模一样
Claims claims = Jwts.parser() // 得到DefaultJwtParser
.setSigningKey(key) // 设置签名的秘钥
.parseClaimsJws(jwt).getBody(); // 设置需要解析的jwt
return claims;
}
}