S SmartDocs
Série: Java java 85 lignes · Mis à jour 2026-04-09

JwtUtil.java

Java/Baasid/src/main/java/com/baasid/security/JwtUtil.java

package com.baasid.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

/**
 * JWT 產生、解析與驗證。金鑰與過期時間由設定檔 {@code jwt.secret}、{@code jwt.expiration-ms} 注入。
 * <p>
 * Token 的 {@code subject} 存放使用者 ID(UUID 字串),自訂 claim {@code account} 存放登入帳號。
 */
@Component
public class JwtUtil {

    private final SecretKey key;
    private final long expirationMs;

    public JwtUtil(
            @Value("${jwt.secret}") String secret,
            @Value("${jwt.expiration-ms}") long expirationMs) {
        this.key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
        this.expirationMs = expirationMs;
    }

    /**
     * 簽發 HS256 JWT,含發行時間、過期時間與帳號 claim。
     *
     * @param userId  使用者主鍵,寫入 {@code subject}
     * @param account 登入帳號,寫入 claim {@code account}
     * @return 壓縮後的 JWT 字串(不含 {@code Bearer } 前綴)
     */
    public String generateToken(UUID userId, String account) {
        Date now = new Date();
        Date expiry = new Date(now.getTime() + expirationMs);

        return Jwts.builder()
                .subject(userId.toString())
                .claim("account", account)
                .issuedAt(now)
                .expiration(expiry)
                .signWith(key)
                .compact();
    }

    /**
     * 驗證簽章並解析 payload;簽章無效或過期會拋出 {@link JwtException}。
     */
    public Claims parseToken(String token) {
        return Jwts.parser()
                .verifyWith(key)
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    /** 從 token 的 subject 還原使用者 {@link UUID}。 */
    public UUID getUserId(String token) {
        return UUID.fromString(parseToken(token).getSubject());
    }

    /** 讀取自訂 claim {@code account}。 */
    public String getAccount(String token) {
        return parseToken(token).get("account", String.class);
    }

    /**
     * 嘗試解析 token,成功則為合法;任何簽章、格式、過期問題皆回傳 {@code false}。
     */
    public boolean isValid(String token) {
        try {
            parseToken(token);
            return true;
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }
}

Articles liés