1. JwtUtil = 토큰에 관련된 암호화, 복호화, 검증 로직이 이루어지는 곳

Copy
@Slf4j

@Component

@RequiredArgsConstructor

public class JwtUtil {

    private final RefreshTokenRepository refreshTokenRepository;

    private final UserDetailsServiceImpl userDetailsService;

    private static final String BEARER_PREFIX = "Bearer ";

    private static final long ACCESS_TIME = 60 * 60 * 1000L;// ACCESS_TIME 1시간
    private static final long REFRESH_TIME = 7 * 24 * 60 * 60 * 1000L;// REFRESH_TIME 7일
    public static final String ACCESS_TOKEN = "Access_Token";

    public static final String REFRESH_TOKEN = "Refresh_Token";

    @Value("${jwt.secret.key}")

    private String secretKey;

    private Key key;

    private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    @PostConstruct

    public void init() {

        byte[] bytes = Base64.getDecoder().decode(secretKey);

        key = Keys.hmacShaKeyFor(bytes);

    }

// header 토큰을 가져오는 기능
    public String getHeaderToken(HttpServletRequest request, String type) {

        return type.equals("Access") ? request.getHeader(ACCESS_TOKEN) :request.getHeader(REFRESH_TOKEN);

    }

// 토큰 생성
    public TokenDto createAllToken(String email) {

        return new TokenDto(createToken(email, "Access"), createToken(email, "Refresh"));

    }

    public String createToken(String email, String type) {

//현재 시각
        Date date = new Date();

//지속 시간
        long time = type.equals("Access") ? ACCESS_TIME : REFRESH_TIME;

        return Jwts.builder()

                .setSubject(email)

                .setExpiration(new Date(date.getTime() + time))

                .setIssuedAt(date)

                .signWith(key, signatureAlgorithm)

                .compact();

    }

    public boolean validateToken(String token) {

        try {

            Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);

            return true;

        } catch (SecurityException | MalformedJwtException e) {

            throw new CustomException(LOGIN_WRONG_SIGNATURE_JWT_TOKEN);

        } catch (ExpiredJwtException e) {

            throw new CustomException(LOGIN_EXPIRED_JWT_TOKEN);

        } catch (UnsupportedJwtException e) {

            throw new CustomException(LOGIN_NOT_SUPPORTED_JWT_TOKEN);

        } catch (IllegalArgumentException e) {

            throw new CustomException(LOGIN_WRONG_FORM_JWT_TOKEN);

        } catch (SignatureException e) {

            throw new CustomException(SIGNATURE_EXCEPTION);

        }

    }

// refreshToken 토큰 검증
    public Boolean refreshTokenValidation(String token) {

// 1차 토큰 검증
        if(!validateToken(token)) return false;

// DB에 저장한 토큰 비교
        Optional<RefreshToken> refreshToken = Optional.ofNullable(refreshTokenRepository.findByEmail(getUserInfoFromToken(token)));

        return refreshToken.isPresent() && token.equals(refreshToken.get().getRefreshToken());

    }

// 토큰에서 loginId 가져오는 기능
    public String getUserInfoFromToken(String token) {

        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody().getSubject();

    }

// 인증 객체 생성
    public Authentication createAuthentication(String email) {

        UserDetails userDetails = userDetailsService.loadUserByUsername(email);

        return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

    }

}

1. init()

2. getHeaderToken()

3. createToken() / createAllTolen()

4. validateToken/refreshTokenValidation