package com.jsowell.common.util; import com.jsowell.common.constant.Constants; import com.jsowell.common.enums.ykc.ReturnCodeEnum; import com.jsowell.common.exception.BusinessException; import io.jsonwebtoken.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import javax.xml.bind.DatatypeConverter; import java.security.Key; import java.util.Date; @Component public class JWTUtils { private static final Logger logger = LoggerFactory.getLogger(JWTUtils.class); // 令牌自定义标识 private static String header; @Value("${token.header}") public void setHeader(String header) { JWTUtils.header = header; } // 令牌秘钥 private static String secret; @Value("${token.secret}") public void setSecret(String secret) { JWTUtils.secret = secret; } // 接口服务 令牌有效期 private static int serviceExpireTime; @Value("${token.serviceExpireTime}") public void setServiceExpireTime(int serviceExpireTime) { JWTUtils.serviceExpireTime = serviceExpireTime; } protected static final long MILLIS_SECOND = 1000; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; // 第三方平台token过期时间 24小时 public static final long ttlMillis = 60 * 60 * 24 * 1000; /** * 生成Jwt的方法 * * @param id 用户ID * @param subject 用户昵称 * @param ttlMillis 过期时间 毫秒 * @return Token String 凭证 */ public static String createToken(String id, String subject, long ttlMillis) { // 签名方法 HS256 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; // 生成Jwt的时间 long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); // 生成秘钥 byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secret); Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); // 设置JWT所存储的信息 JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject).signWith(signatureAlgorithm, signingKey); //builder.claim("name", "value"); //存储自定义信息 // 设置过期时间 if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis * MILLIS_MINUTE; Date exp = new Date(expMillis); builder.setExpiration(exp); } // 构建JWT并将其序列化为紧凑的URL安全字符串 return builder.compact(); } /** * 从令牌中获取数据声明 * * @param token 令牌 * @return 数据声明 */ private static Claims parseToken(String token) { Claims claims = null; try { claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } catch (ExpiredJwtException e) { logger.error("parseToken error", e); throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } return claims; } /** * 获取会员token * * @return */ public static String createMemberToken(String memberId, String nickName) { return createToken(memberId, nickName, serviceExpireTime); } /** * 获取会员id * * @param memberToken * @return */ public static String getMemberId(String memberToken) { memberToken = getToken(memberToken); if (StringUtils.isBlank(memberToken)) { logger.error("获取会员id memberToken为空"); throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } Claims claims = parseToken(memberToken); return claims.getId(); } /** * 校验第三方平台token * @param token 第三方平台token * @return */ public static boolean checkThirdPartyToken(String token) { token = getToken(token); if (StringUtils.isBlank(token)) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } Claims claims = parseToken(token); return StringUtils.isNotBlank(claims.getId()); } public static boolean checkThirdPartyToken(HttpServletRequest request) { if (request == null) { throw new BusinessException(ReturnCodeEnum.CODE_TOKEN_ERROR); } // 校验令牌 String token = request.getHeader("Authorization"); return checkThirdPartyToken(token); } /** * 替换Bearer * * @param memberToken 会员token * @return */ private static String getToken(String memberToken) { if (StringUtils.isNotEmpty(memberToken) && memberToken.startsWith(Constants.TOKEN_PREFIX)) { memberToken = memberToken.replace(Constants.TOKEN_PREFIX, "").trim(); } return memberToken; } public static void main(String[] args) { long ttlMillis = 60 * 60 * 24 * 1000; String token = createToken("I4XLPQPV", "3DSBTWHVIC6KVCKI", ttlMillis); System.out.println(checkThirdPartyToken(token)); } }