package com.nms.swspkmas_standalone.utils;
|
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.util.StrUtil;
|
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.SignatureAlgorithm;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Value;
|
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* JwtToken生成的工具类
|
* JWT token的格式:header.payload.signature
|
* header的格式(算法、token的类型):
|
* {"alg": "HS512","typ": "JWT"}
|
* payload的格式(用户名、创建时间、生成时间):
|
* {"sub":"wang","created":1489079981393,"exp":1489684781}
|
* signature的生成算法:
|
* HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
|
*/
|
public class JwtTokenUtil {
|
private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
|
|
public static final String USER_LOGIN_TOKEN="Authorization";
|
|
public static final String CLAIM_KEY_USERNAME = "sub";
|
public static final String CLAIM_KEY_CREATED = "created";
|
|
public static String SECRET="nms-secret";
|
|
public static Long EXPIRATION=604800L; //JWT的超期限时间(60*60*24*7)
|
|
|
/**
|
* 根据负责生成JWT的token
|
*/
|
public static String generateToken(Map<String, Object> claims) {
|
return Jwts.builder()
|
.setClaims(claims)
|
.setExpiration(generateExpirationDate())
|
.signWith(SignatureAlgorithm.HS512, SECRET)
|
.compact();
|
}
|
|
/**
|
* 从token中获取JWT中的负载
|
*/
|
public static Claims getClaimsFromToken(String token) {
|
Claims claims = null;
|
try {
|
claims = Jwts.parser()
|
.setSigningKey(SECRET)
|
.parseClaimsJws(token)
|
.getBody();
|
} catch (Exception e) {
|
LOGGER.info("JWT格式验证失败:{}", token);
|
}
|
return claims;
|
}
|
|
/**
|
* 生成token的过期时间
|
*/
|
public static Date generateExpirationDate() {
|
return new Date(System.currentTimeMillis() + EXPIRATION * 1000);
|
}
|
|
/**
|
* 从token中获取登录用户名
|
*/
|
public static String getUserNameFromToken(String token) {
|
String username;
|
try {
|
Claims claims = getClaimsFromToken(token);
|
username = claims.getSubject();
|
} catch (Exception e) {
|
username = null;
|
}
|
return username;
|
}
|
|
/**
|
* 验证token是否还有效
|
*
|
* @param token 客户端传入的token
|
* @param uname 从数据库中查询出来的用户信息
|
*/
|
public static boolean validateToken(String token, String uname) {
|
String username = getUserNameFromToken(token);
|
return username.equals(uname) && !isTokenExpired(token);
|
}
|
|
/**
|
* 判断token是否已经失效
|
*/
|
public static boolean isTokenExpired(String token) {
|
Date expiredDate = getExpiredDateFromToken(token);
|
return expiredDate.before(new Date());
|
}
|
|
/**
|
* 从token中获取过期时间
|
*/
|
public static Date getExpiredDateFromToken(String token) {
|
Claims claims = getClaimsFromToken(token);
|
return claims.getExpiration();
|
}
|
|
/**
|
* 根据用户信息生成token
|
*/
|
public static String generateToken(String username) {
|
Map<String, Object> claims = new HashMap<>();
|
claims.put(CLAIM_KEY_USERNAME, username);
|
claims.put(CLAIM_KEY_CREATED, new Date());
|
return generateToken(claims);
|
}
|
|
/**
|
* 当原来的token没过期时是可以刷新的
|
*
|
* @param oldToken 带tokenHead的token
|
*/
|
// public static String refreshHeadToken(String oldToken) {
|
// if(StrUtil.isEmpty(oldToken)){
|
// return null;
|
// }
|
// String token = oldToken.substring(tokenHead.length());
|
// if(StrUtil.isEmpty(token)){
|
// return null;
|
// }
|
// //token校验不通过
|
// Claims claims = getClaimsFromToken(token);
|
// if(claims==null){
|
// return null;
|
// }
|
// //如果token已经过期,不支持刷新
|
// if(isTokenExpired(token)){
|
// return null;
|
// }
|
// //如果token在30分钟之内刚刷新过,返回原token
|
// if(tokenRefreshJustBefore(token,30*60)){
|
// return token;
|
// }else{
|
// claims.put(CLAIM_KEY_CREATED, new Date());
|
// return generateToken(claims);
|
// }
|
// }
|
|
/**
|
* 判断token在指定时间内是否刚刚刷新过
|
* @param token 原token
|
* @param time 指定时间(秒)
|
*/
|
public static boolean tokenRefreshJustBefore(String token, int time) {
|
Claims claims = getClaimsFromToken(token);
|
Date created = claims.get(CLAIM_KEY_CREATED, Date.class);
|
Date refreshDate = new Date();
|
//刷新时间在创建时间的指定时间内
|
if(refreshDate.after(created)&&refreshDate.before(DateUtil.offsetSecond(created,time))){
|
return true;
|
}
|
return false;
|
}
|
|
|
}
|