JWTUtils.java 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package com.yunzhi.demo.common;
  2. import io.jsonwebtoken.Claims;
  3. import io.jsonwebtoken.Jws;
  4. import io.jsonwebtoken.Jwts;
  5. import io.jsonwebtoken.security.Keys;
  6. import lombok.extern.slf4j.Slf4j;
  7. import javax.crypto.SecretKey;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.time.LocalDateTime;
  11. import java.time.ZoneId;
  12. import java.util.Base64;
  13. import java.util.Date;
  14. import java.util.Map;
  15. /**
  16. * JWTUtils
  17. * jwt 辅助类
  18. * https://github.com/jwtk/jjwt
  19. */
  20. @Slf4j
  21. public class JWTUtils {
  22. // 过期时间 30 分钟
  23. public static final long EXPIRE_TIME = 30 * 60;
  24. // 私钥
  25. static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(Base64.getEncoder().encode("Yansen is so handsome. He is a good man. Everyone like him !!!".getBytes()));
  26. // 请求头
  27. public static final String AUTH_HEADER = "X-Authorization-JWT";
  28. /**
  29. * 生成 token, claims 里必须要有 userId
  30. * @param claims
  31. * @return
  32. */
  33. public static String encode(Map<String, Object> claims) {
  34. Date[] datePair = getDatePair();
  35. Date iat = datePair[0];
  36. Date exp = datePair[1];
  37. return Jwts.builder().setIssuer(claims.get("userId").toString()).setIssuedAt(iat).setExpiration(exp).addClaims(claims).signWith(SECRET_KEY).compact();
  38. }
  39. public static Map<String, Object> decode(String token) throws Exception {
  40. return parse(token);
  41. }
  42. public static String refresh(String token) {
  43. try {
  44. Claims claims = parse(token);
  45. Integer iat = (Integer) claims.get("iat");
  46. if (null != iat) {
  47. long currentTime = System.currentTimeMillis() / 1000;
  48. int oneMinute = 60;
  49. if (currentTime - iat < oneMinute) {
  50. return token;
  51. }
  52. }
  53. claims.remove("iat");
  54. claims.remove("exp");
  55. return encode(claims);
  56. } catch (Exception e) {
  57. log.error("解析 JWT Token 失败: {}", e.getMessage());
  58. }
  59. return null;
  60. }
  61. public static void refresh(String jws, HttpServletResponse response) {
  62. if (!StringUtils.isEmpty(jws)) {
  63. String token = refresh(jws);
  64. response.addHeader(AUTH_HEADER, token);
  65. }
  66. }
  67. public static String getToken(HttpServletRequest request) {
  68. return request.getHeader(AUTH_HEADER);
  69. }
  70. public static void verify(String token) throws Exception {
  71. parse(token);
  72. }
  73. private static Date[] getDatePair() {
  74. LocalDateTime now = LocalDateTime.now();
  75. Date iat = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
  76. Date exp = Date.from(now.plusSeconds(EXPIRE_TIME).atZone(ZoneId.systemDefault()).toInstant());
  77. return new Date[]{iat, exp};
  78. }
  79. private static Claims parse(String token) throws Exception {
  80. if (token == null || "".equals(token)) {
  81. throw new Exception("Token 不能为空");
  82. }
  83. long skew = 5;
  84. Jws<Claims> claimsJws = Jwts.parserBuilder().setAllowedClockSkewSeconds(skew).setSigningKey(SECRET_KEY).build().parseClaimsJws(token);
  85. return claimsJws.getBody();
  86. }
  87. }