diff --git a/src/main/java/univ/yesummit/global/auth/util/JwtUtils.java b/src/main/java/univ/yesummit/global/auth/util/JwtUtils.java new file mode 100644 index 0000000..4d2b803 --- /dev/null +++ b/src/main/java/univ/yesummit/global/auth/util/JwtUtils.java @@ -0,0 +1,105 @@ +package univ.yesummit.global.auth.util; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import univ.yesummit.domain.member.repository.MemberRepository; + +import java.util.Date; +import java.util.Optional; + +@Getter +@Service +@RequiredArgsConstructor +@Slf4j +public class JwtUtils { + + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.access.expiration}") + private Long accessExpiration; + + @Value("${jwt.refresh.expiration}") + private Long refreshExpiration; + + @Value("${jwt.access.header}") + private String accessHeader; + + @Value("${jwt.refresh.header}") + private String refreshHeader; + + private static final String ACCESS_TOKEN_SUBJECT = "AccessToken"; + private static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; + private static final String ID_CLAIM = "member_id"; + private static final String BEARER = "Bearer "; + + private final MemberRepository memberRepository; + + public String createAccessToken(Long memberId) { + + log.info("memberId info: {}", memberId.toString()); + + String accessToken = JWT.create() + .withSubject(ACCESS_TOKEN_SUBJECT) + .withExpiresAt(new Date(System.currentTimeMillis() + accessExpiration)) + .withClaim(ID_CLAIM, memberId) + .sign(Algorithm.HMAC512(secret)); + + + log.info("Generated Access Token: {}", accessToken); + + return accessToken; + } + + + public String createRefreshToken() { + return JWT.create() + .withSubject(REFRESH_TOKEN_SUBJECT) + .withExpiresAt(new Date(System.currentTimeMillis() + refreshExpiration)) + .sign(Algorithm.HMAC512(secret)); + } + + public void sendAccessAndRefreshToken(HttpServletResponse response, String accessToken, String refreshToken) { + response.setStatus(HttpServletResponse.SC_OK); + + response.setHeader(accessHeader, accessToken); + response.setHeader(refreshHeader, refreshToken); + log.info("Access Token: {}, Refresh Token: {}", accessToken, refreshToken); + } + + public Optional extractAccessToken(HttpServletRequest request) { + String header = request.getHeader(accessHeader); + log.info("Access header: {}", header); + return Optional.ofNullable(request.getHeader(accessHeader)) + .filter(accessToken -> accessToken.startsWith(BEARER)) + .map(accessToken -> accessToken.replace(BEARER, "")); + } + + public Optional extractMemberId(String token) { + Long memberId = JWT.require(Algorithm.HMAC512(secret)) + .build() + .verify(token) + .getClaim("member_id") + .asLong(); + + return Optional.ofNullable(memberId); + } + /* 토큰 유효성 검증 */ + public boolean isValid(String token) { + try { + JWT.require(Algorithm.HMAC512(secret)).build().verify(token); + return true; + } catch (Exception e) { + log.error("유효하지 않은 Token입니다", e.getMessage()); + return false; + } + } + //==========================================================================// +} \ No newline at end of file