diff --git a/backend/src/main/java/net/pengcook/authentication/service/LoginService.java b/backend/src/main/java/net/pengcook/authentication/service/LoginService.java index 1c708887..1122f62a 100644 --- a/backend/src/main/java/net/pengcook/authentication/service/LoginService.java +++ b/backend/src/main/java/net/pengcook/authentication/service/LoginService.java @@ -9,9 +9,11 @@ import net.pengcook.authentication.dto.GoogleSignUpRequest; import net.pengcook.authentication.dto.GoogleSignUpResponse; import net.pengcook.authentication.dto.TokenPayload; +import net.pengcook.authentication.exception.AuthenticationException; import net.pengcook.authentication.util.JwtTokenManager; import net.pengcook.user.domain.User; import net.pengcook.user.repository.UserRepository; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @Service @@ -39,7 +41,7 @@ public GoogleSignUpResponse signUpWithGoogle(GoogleSignUpRequest googleSignUpReq User user = createUser(googleSignUpRequest); if (userRepository.existsByEmail(user.getEmail())) { - throw new IllegalArgumentException("Email already exists."); + throw new AuthenticationException(HttpStatus.BAD_REQUEST, "중복 이메일 가입 시도", "이미 가입된 이메일입니다."); } User savedUser = userRepository.save(user); @@ -65,7 +67,7 @@ private FirebaseToken decodeIdToken(String idToken) { try { return firebaseAuth.verifyIdToken(idToken); } catch (FirebaseAuthException e) { - throw new IllegalArgumentException("Invalid Google ID token."); + throw new AuthenticationException(HttpStatus.UNAUTHORIZED, "구글 인증 실패", "구글 인증에 실패했습니다."); } } } diff --git a/backend/src/main/java/net/pengcook/authentication/util/JwtTokenManager.java b/backend/src/main/java/net/pengcook/authentication/util/JwtTokenManager.java index 965cf897..8cdecf71 100644 --- a/backend/src/main/java/net/pengcook/authentication/util/JwtTokenManager.java +++ b/backend/src/main/java/net/pengcook/authentication/util/JwtTokenManager.java @@ -7,7 +7,9 @@ import com.auth0.jwt.interfaces.DecodedJWT; import java.util.Date; import net.pengcook.authentication.dto.TokenPayload; +import net.pengcook.authentication.exception.AuthenticationException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component @@ -42,10 +44,9 @@ public TokenPayload extract(String token) { JWTVerifier jwtVerifier = JWT.require(secretAlgorithm).build(); try { DecodedJWT decodedJWT = jwtVerifier.verify(token); - return getTokenPayload(decodedJWT); } catch (JWTVerificationException e) { - throw new IllegalArgumentException(e); + throw new AuthenticationException(HttpStatus.UNAUTHORIZED, "토큰 검증 실패", "유효하지 않은 토큰입니다."); } } diff --git a/backend/src/main/java/net/pengcook/authentication/util/TokenExtractor.java b/backend/src/main/java/net/pengcook/authentication/util/TokenExtractor.java index 5088f04e..8d014a07 100644 --- a/backend/src/main/java/net/pengcook/authentication/util/TokenExtractor.java +++ b/backend/src/main/java/net/pengcook/authentication/util/TokenExtractor.java @@ -1,5 +1,7 @@ package net.pengcook.authentication.util; +import net.pengcook.authentication.exception.AuthenticationException; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @Component @@ -9,10 +11,10 @@ public class TokenExtractor { public String extractToken(String authorizationHeader) { if (authorizationHeader == null) { - throw new IllegalArgumentException("Authorization header is required."); + throw new AuthenticationException(HttpStatus.BAD_REQUEST, "인증 헤더 없음", "인증 헤더가 존재하지 않습니다."); } if (!authorizationHeader.startsWith(BEARER)) { - throw new IllegalArgumentException("Invalid Authorization header."); + throw new AuthenticationException(HttpStatus.BAD_REQUEST, "인증 헤더 오류", "인증 헤더는 Bearer로 시작해야 합니다."); } return authorizationHeader.substring(BEARER.length()); } diff --git a/backend/src/test/java/net/pengcook/authentication/controller/LoginControllerTest.java b/backend/src/test/java/net/pengcook/authentication/controller/LoginControllerTest.java index d02b058e..6046a17f 100644 --- a/backend/src/test/java/net/pengcook/authentication/controller/LoginControllerTest.java +++ b/backend/src/test/java/net/pengcook/authentication/controller/LoginControllerTest.java @@ -141,6 +141,6 @@ void signUpWithGoogleWhenEmailAleadyRegistered() throws FirebaseAuthException { .body(request) .when().post("/api/oauth/google/sign-up") .then().log().all() - .statusCode(500); // TODO : Exception Handler 생성후 적절한 상태코드로 변경 + .statusCode(400); } } diff --git a/backend/src/test/java/net/pengcook/authentication/service/LoginServiceTest.java b/backend/src/test/java/net/pengcook/authentication/service/LoginServiceTest.java index d2c0175e..39f9ad1c 100644 --- a/backend/src/test/java/net/pengcook/authentication/service/LoginServiceTest.java +++ b/backend/src/test/java/net/pengcook/authentication/service/LoginServiceTest.java @@ -14,6 +14,7 @@ import net.pengcook.authentication.dto.GoogleLoginResponse; import net.pengcook.authentication.dto.GoogleSignUpRequest; import net.pengcook.authentication.dto.GoogleSignUpResponse; +import net.pengcook.authentication.exception.AuthenticationException; import net.pengcook.authentication.util.JwtTokenManager; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -117,7 +118,7 @@ void signUpWithGoogleWhenEmailAleadyRegistered() throws FirebaseAuthException { when(firebaseAuth.verifyIdToken(idToken)).thenReturn(firebaseToken); assertThatThrownBy(() -> loginService.signUpWithGoogle(request)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Email already exists."); + .isInstanceOf(AuthenticationException.class) + .hasMessage("이미 가입된 이메일입니다."); } } diff --git a/backend/src/test/java/net/pengcook/authentication/util/JwtTokenManagerTest.java b/backend/src/test/java/net/pengcook/authentication/util/JwtTokenManagerTest.java index 4f45828d..a9d47828 100644 --- a/backend/src/test/java/net/pengcook/authentication/util/JwtTokenManagerTest.java +++ b/backend/src/test/java/net/pengcook/authentication/util/JwtTokenManagerTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import net.pengcook.authentication.dto.TokenPayload; +import net.pengcook.authentication.exception.AuthenticationException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -40,6 +41,7 @@ void extractWhenInvalidToken() { String accessToken = "fakefakefakefakefake.accessaccessaccessaccess.tokentokentokentokentoken"; assertThatThrownBy(() -> jwtTokenManager.extract(accessToken)) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(AuthenticationException.class) + .hasMessage("유효하지 않은 토큰입니다."); } } diff --git a/backend/src/test/java/net/pengcook/authentication/util/TokenExtractorTest.java b/backend/src/test/java/net/pengcook/authentication/util/TokenExtractorTest.java index 17627c58..8c09471f 100644 --- a/backend/src/test/java/net/pengcook/authentication/util/TokenExtractorTest.java +++ b/backend/src/test/java/net/pengcook/authentication/util/TokenExtractorTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import net.pengcook.authentication.exception.AuthenticationException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -26,8 +27,8 @@ void extractTokenWhenAuthorizationHeaderNull() { String authorizationHeader = null; assertThatThrownBy(() -> tokenExtractor.extractToken(authorizationHeader)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Authorization header is required."); + .isInstanceOf(AuthenticationException.class) + .hasMessage("인증 헤더가 존재하지 않습니다."); } @Test @@ -36,7 +37,7 @@ void extractTokenWhenAuthorizationHeaderNotStartWithBearer() { String authorizationHeader = "Not Bearer token"; assertThatThrownBy(() -> tokenExtractor.extractToken(authorizationHeader)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Invalid Authorization header."); + .isInstanceOf(AuthenticationException.class) + .hasMessage("인증 헤더는 Bearer로 시작해야 합니다."); } }