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<String, Object> 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<String, Object> 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);
|
}
|
}
|