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 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 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; } }