Jwt token生成的方式有几种,可根据具体情况决定生成方式,以下为本人使用的一种,仅供参考。JWT官网链接
1.jwt生成的Token格式
eyJhbGciOiJIUzI1NiJ9.eyJqd3RDbGFpbSI6eyJ1c2VySWQiOiIyIiwiYXBpSWRzIjoiMSwyLDMiLCJuYW1lIjpudWxsfSwiaWF0IjoxNjMwNDg3MjA5LCJleHAiOjE2MzA0OTQ0MDl9.apV5AqF6tgeVOcZZgHztsoGVCsv8b-M3ipExC6E7eUE
2.jwt生成Token的结构
2.1 jwt生成的token由三部分组成
Header(头部)Payload(负载)Signature(签名)
格式为:Header.PayLoad.Signature (中间由符号“.”链接)与生成的token相对应
2.2 Header
{
"alg": "HS256",
"typ": "JWT"
}
alg表示签名的算法,默认为SHA256,写作“HS256”,typ表示令牌的类型,JWT统一为“JWT“
2.3 Payload
Payload官方名称为负载,用来存放实际需要存放的数据,官方给出了7个参考字段,也可以自定义参数,在这里需要注意的是这部分是json对象根据Base64转化而成,不进行加密,所以需要注意不要存储私密信息。
//官方推荐参数
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
2.4 Signature
Signature是由Header加Payload根据密钥(secret自行设置)以及指定的加密方式生成
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
3.jwt token生成
3.1 引入jar包
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version> 3.10.0</version>
</dependency>
3.2 生成,解析Token
token生成我使用了两种方式,最终采用了第一种,原因是更简洁,和自定义数据存取方便,大家在使用时可以根据自己情况使用。
public class JwtUtils {
public static final String CLAIM_NAME = "jwtClaim";
/**
* 生成 jwt token
*/
public static String creatJwt(JwtClaim jwtClaim, Long tokenExpireTime, String secretKey) {
Date now = new Date();
Date date = new Date(now.getTime() + tokenExpireTime);//根据当前时间 + tokenExpireTime(token有效期,以毫秒为单位 例:7200000为2小时)
return Jwts.builder()
.claim(CLAIM_NAME, jwtClaim)//jwtClaim为自定义对象,存放自定义参数(数据存放在Payload)
.setIssuedAt(now)//生成时间
.setExpiration(date)//token到期时间
.signWith(SignatureAlgorithm.HS256, secretKey)//加密方式,secretKey自定义密钥
.compact();
}
/**
* 解析 jwt
*/
public static Claims parseJwt(String token, String secretKey) {
try {
//注掉代码为完整的获取自定义对象参数的方式,为注掉的为我工具类方法
// JwtTokenDto jwtTokenDto = new JwtTokenDto();
// Claims body = Jwts.parser()
// .setSigningKey(secretKey)//secretKey密钥
// .parseClaimsJws(token)//需要解析的token
// .getBody();//获取存入的参数及自定义的jwtClaim对象中的参数
// BeanUtil.copyProperties(body.get(JwtUtils.CLAIM_NAME), jwtTokenDto);
// return jwtTokenDto;
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
} catch (ExpiredJwtException e) {//此异常为生成的token过期异常
log.info("校验的token过期!");
throw new BusinessException("Token过期!", ResponseParameter.CODE_HTTP_XXX);//自定义异常处理类
}
}
//第二种token生成方式
// /**
// * 生成 jwt token
// */
// public static String creatJwtTo(String userId){
//
// Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);//SECRET_KEY自定义密钥
// // 设置头信息
// HashMap<String, Object> header = new HashMap<>(2);
// header.put("typ","JWT");
// header.put("alg","HS256");
//
// TokenVo tokenVo = new TokenVo();
// // 生成 Token
// String token = JWT.create().withHeader(header)
//
// .withClaim("userId", userId)//自定义参数
// .withClaim("userName",header)//自定义参数
// .withClaim("test","test")//自定义参数
// .withExpiresAt(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME)).sign(algorithm);//TOKEN_EXPIRE_TIME token过期时间毫秒
// return token;
//
// }
//
//
// /**
// * 解析 jwt
// */
// public static Map<String, Claim> parseJwtTo(String token){
// Map<String, Claim> claims = null;
// try {
// Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);//SECRET_KEY自定义密钥
// JWTVerifier verifier = JWT.require(algorithm).build();
// DecodedJWT jwt = verifier.verify(token);//需要解析token
// claims = jwt.getClaims();
// return claims;
// } catch (Exception e) {
// return null;
// }
// }
}