jwt工具類

xiaoovo發表於2024-04-18
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

/**
 * JWT 工具類
 *
 * @author stonffe
 * @date 2024/4/18
 */
@ConditionalOnProperty("novel.jwt.secret")
@Component
@Slf4j
public class JwtUtils {

    /**
     * 注入JWT加密金鑰
     */
    @Value("${novel.jwt.secret}")
    private String secret;

    /**
     * 定義系統標識頭常量
     */
    private static final String HEADER_SYSTEM_KEY = "systemKeyHeader";

    /**
     * 根據使用者ID生成JWT
     *
     * @param uid       使用者ID
     * @param systemKey 系統標識
     * @return JWT
     */
    public String generateToken(Long uid, String systemKey) {
        long nowMillis = System.currentTimeMillis();
        long expMillis = nowMillis + 60 * 60 * 1000;
        return Jwts.builder()
                .setHeaderParam(HEADER_SYSTEM_KEY, systemKey)
                .setSubject(uid.toString())
//                .setExpiration(new Date(expMillis))
                .signWith(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)))
                .compact();
    }

    /**
     * 解析JWT返回使用者ID
     *
     * @param token     JWT
     * @param systemKey 系統標識
     * @return 使用者ID
     */
    public Long parseToken(String token, String systemKey) {
        Jws<Claims> claimsJws;
        try {
            claimsJws = Jwts.parserBuilder()
                    .setSigningKey(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)))
                    .build()
                    .parseClaimsJws(token);
            // OK, we can trust this JWT
            // 判斷該 JWT 是否屬於指定系統
            if (Objects.equals(claimsJws.getHeader().get(HEADER_SYSTEM_KEY), systemKey)) {
                return Long.parseLong(claimsJws.getBody().getSubject());
            }
        } catch (JwtException e) {
            log.warn("JWT解析失敗:{}", token);
            // don't trust the JWT!
        }
        return null;
    }

}