package com.common.core.utils; import com.common.core.constant.GlobalConst; import com.common.redis.util.RedisUtil; import com.common.security.configure.AppDetails; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** * @author 廖振钦 * @date 2022-01-17 */ @Slf4j @Component public class JwtTokenUtil { @Autowired private RedisUtil redisUtil; public static final String CLAIM_KEY_APPID = "appid"; public static final String CLAIM_KEY_USERID = "userid"; private static final String CLAIM_KEY_CREATED = "created"; private Long expiration = GlobalConst.TOKEN_EXPIRE+GlobalConst.TOKEN_EXPIRE_BUFF; /** * 根据负责生成JWT的token */ private String generateToken(Map claims) { return Jwts.builder() .setClaims(claims) .setExpiration(generateExpirationDate()) .signWith(SignatureAlgorithm.HS512, SM4Utils.getPassword()) .compact(); } /** * 从token中获取JWT中的负载 */ private Claims getClaimsFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SM4Utils.getPassword()) .parseClaimsJws(token) .getBody(); return claims; } /** * 生成token的过期时间 */ private Date generateExpirationDate() { return new Date(System.currentTimeMillis() + expiration * 1000); } /** * 从token中获取登录用户名 */ public String getAppidFromToken(String token) { String appid; try { Claims claims = getClaimsFromToken(token); appid = claims.get(CLAIM_KEY_APPID).toString(); } catch (Exception e) { log.error("getAppidFromToken error:",e); appid = null; } return appid; } /** * 从token中获取登录用户名 */ public String getUseridFromToken(String token) { String userid; try { Claims claims = getClaimsFromToken(token); userid = claims.get(CLAIM_KEY_USERID)==null? "" : claims.get(CLAIM_KEY_USERID).toString(); } catch (Exception e) { log.error("getUseridFromToken error:",e); userid = null; } return userid; } public Claims getClaim(String token) { try { Claims claims = getClaimsFromToken(token); return claims; } catch (Exception e) { log.error("getClaim error:",e); return null; } } /** * 验证token是否还有效 * * @param token 客户端传入的token * @param userDetails 从数据库中查询出来的用户信息 */ public boolean validateToken(String token, UserDetails userDetails) { String key= GlobalConst.TOKEN_KEY+userDetails.getUsername(); String tmpKey= GlobalConst.TOKEN_KEY_TMP+userDetails.getUsername(); Object useridobject = getClaim(token).get(JwtTokenUtil.CLAIM_KEY_USERID); if(!Objects.isNull(useridobject)){ key +=":"+useridobject.toString(); tmpKey +=":"+useridobject.toString(); } return (redisUtil.get(key) !=null && token.equals(redisUtil.get(key).toString()) && !isTokenExpired(token)) ||(redisUtil.get(tmpKey) !=null && token.equals(redisUtil.get(tmpKey).toString()) && !isTokenExpired(token)); } /** * 判断token是否已经失效 */ private boolean isTokenExpired(String token) { Date expiredDate = getExpiredDateFromToken(token); return expiredDate.before(new Date()); } /** * 从token中获取过期时间 */ private Date getExpiredDateFromToken(String token) { Claims claims = getClaimsFromToken(token); return claims.getExpiration(); } /** * 根据用户信息生成token */ public String generateToken(AppDetails userDetails) { Map claims = new HashMap<>(); claims.put(CLAIM_KEY_APPID, userDetails.getUsername()); if(StringUtils.isNotEmpty(userDetails.getUserid())){ claims.put(CLAIM_KEY_USERID, userDetails.getUserid()); } claims.put(CLAIM_KEY_CREATED, new Date()); return generateToken(claims); } /** * 判断token是否可以被刷新 */ public boolean canRefresh(String token) { return !isTokenExpired(token); } /** * 刷新token */ public String refreshToken(String token) { Claims claims = getClaimsFromToken(token); claims.put(CLAIM_KEY_CREATED, new Date()); return generateToken(claims); } }