Skip to content

Conversation

@Shinjongyun
Copy link
Contributor

@Shinjongyun Shinjongyun commented Oct 3, 2025

Related issue 🛠

  • closed #이슈넘버

Work Description 📝

Token이 만료되거나 유효하지 않은 경우, Http Status를 400으로 반환 했지만, 401 반환이 올바른 것 같아서 이를 수정했습니다!

Screenshot 📸

Uncompleted Tasks 😅

  • Task1

To Reviewers 📢

Summary by CodeRabbit

  • 신기능: 없음
  • 버그 수정
    • 인증/토큰 관련 오류의 HTTP 상태를 400 → 401로 조정하여 만료된 토큰·잘못된 서명 등에서 올바른 Unauthorized 응답을 반환합니다.
    • 토큰 검증 및 인증 실패 시 일관된 오류 응답을 제공합니다.
    • 비밀번호 재발급 시 존재하지 않는 이메일에 대해 명확한 오류를 반환합니다.
  • 리팩터링
    • 인증 오류 코드 명칭 및 일부 불필요 항목을 정리하여 응답 일관성 향상했습니다.

@coderabbitai
Copy link

coderabbitai bot commented Oct 3, 2025

Walkthrough

토큰 검증의 예외 매핑을 포괄적으로 SECURITY_INVALID_TOKEN으로 통일했고, ErrorCode 열거형에서 토큰/인증 관련 상수명·상태·일부 항목(예: LOGIN_FAILED)을 정리·교체했습니다. 몇몇 서비스/핸들러에서 관련 에러 코드 매핑이 업데이트되었습니다.

Changes

Cohort / File(s) Summary of Changes
Auth util / Jwt 검증
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/util/JwtUtil.java
토큰 검증 실패의 포괄 예외 매핑을 SECURITY_INVALID_ACCESS_TOKENSECURITY_INVALID_TOKEN으로 변경
Global ErrorCode enum
src/main/java/com/WhoIsRoom/WhoIs_Server/global/common/response/ErrorCode.java
에러 코드 추가/제거/이름 변경 및 HTTP 상태 조정: USER_MAIL_NOT_FOUND 추가, SECURITY_INVALID_REFRESH_TOKEN 제거 → SECURITY_INVALID_TOKEN 추가, INVALID_REFRESH_TYPE/INVALID_TOKEN_TYPE 추가, LOGIN_FAILED/EMPTY_REFRESH_HEADER 제거, 여러 토큰·인증 관련 항목의 상태를 BAD_REQUESTUNAUTHORIZED로 변경
Auth handler
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/handler/exception/CustomJsonAuthenticationFailureHandler.java
인증 실패 매핑 변경: UsernameNotFoundExceptionSECURITY_UNAUTHORIZED, BadCredentialsExceptionINVALID_EMAIL_OR_PASSWORD 등 매핑 조정
Jwt service flows
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/service/JwtService.java
로그아웃/리이슈/삭제 흐름에서 토큰 타입 검사 시 던지는 에러 코드 INVALID_TOKEN_TYPEINVALID_REFRESH_TYPE로 변경 및 불필요한 import 정리
User service (비밀번호 재발급)
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/user/service/UserService.java
존재하지 않는 사용자 처리 시 USER_NOT_FOUNDUSER_MAIL_NOT_FOUND로 변경 (비밀번호 재발급 경로)

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant API as API
  participant AuthFilter as Auth Filter
  participant JwtUtil as JwtUtil
  participant ErrorCode as ErrorCode Enum
  rect rgb(230, 250, 230)
    note right of JwtUtil: 변경점: 포괄 예외 → SECURITY_INVALID_TOKEN
  end

  Client->>API: 요청 (Authorization: Bearer ...)
  API->>AuthFilter: 인증 검사
  AuthFilter->>JwtUtil: validate(token)
  alt 토큰 유효
    JwtUtil-->>AuthFilter: claims
    AuthFilter-->>API: 인증 통과
    API-->>Client: 200 OK
  else 검증 예외 발생
    JwtUtil->>ErrorCode: 매핑 요청
    ErrorCode-->>AuthFilter: SECURITY_INVALID_TOKEN 등 반환
    AuthFilter-->>Client: 401 / 매핑된 에러 응답
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • yskim6772

Poem

토큰의 길을 정리하니 흐름이 쨍 —
하나로 묶인 오류, 이름도 깔끔히 정돈 🎯
잘못된 열쇠엔 401이 노크하고
사라진 LOGIN_FAILED에 작별을 고하네 👋
에러열거 정리됐으니 로그는 더 담담해졌네

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 제목이 변경의 핵심인 JWT 토큰 응답 HTTP 상태 코드 변경을 정확하게 설명하며 이슈 번호와 HotFix 태그를 통해 배경을 명확히 드러냅니다. 과도한 상세 없이 간결하게 작성되어 스캔 시 이해하기 쉽습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#10-myPage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@yskim6772 yskim6772 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어푸어푸

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/service/JwtService.java (3)

79-84: null 체크 시 에러 코드 선택을 재검토하세요.

null 토큰에 대해 INVALID_REFRESH_TYPE을 사용하는 것은 의미상 약간 어색할 수 있습니다. "type"은 형식 문제를 암시하지만, 여기서는 토큰 자체가 없는 상황입니다.

더 명확한 대안:

  • EMPTY_REFRESH_HEADER가 제거되었다면 ILLEGAL_ARGUMENT 고려
  • 또는 새로운 MISSING_REFRESH_TOKEN 에러 코드 도입

현재 구현도 동작하지만, 향후 에러 메시지 명확성을 위해 검토를 권장합니다.


79-84: deleteRefreshToken의 null 분기 제거 제안
validateToken(null) 시 EMPTY_AUTHORIZATION_HEADER 예외가 발생해 해당 분기는 도달하지 않습니다. 제거를 권장합니다.


79-84: 에러 코드의 의미가 null 체크와 다소 어긋나요.

refreshToken이 null일 때 INVALID_REFRESH_TYPE을 던지고 있는데, 이는 "refresh 타입이 아님"을 의미하므로 null 상황과는 맥락이 다릅니다. EMPTY_REFRESH_HEADER가 제거된 것으로 보이지만, null 체크에는 별도의 에러 코드(예: MISSING_REFRESH_TOKEN)를 추가하는 게 더 명확할 것 같아요.

현재 구조에서는 큰 문제는 없지만, 향후 에러 메시지 명확성을 위해 고려해보세요.

src/main/java/com/WhoIsRoom/WhoIs_Server/global/common/response/ErrorCode.java (3)

42-43: 이메일 인증 코드 오류에 대한 HTTP 상태 코드를 재검토하세요.

INVALID_EMAIL_CODEEXPIRED_EMAIL_CODEUNAUTHORIZED (401)로 변경했지만, 이는 의미적으로 맞지 않을 수 있습니다:

  • 이메일 인증 코드 검증 실패는 인증(authentication) 실패가 아닌 입력 검증(validation) 실패입니다
  • 사용자가 이미 인증되지 않은 상태에서 발생하는 오류이므로 401보다 400이 더 적절할 수 있습니다

JWT 토큰 검증 오류와는 성격이 다른 에러이므로, PR 목표와 별개로 HTTP 상태를 400으로 유지하는 것을 고려하세요.


36-52: 에러 코드 번호 일관성 개선 고려해보세요.

에러 코드 번호가 601, 602, 605로 건너뛰고 있네요 (603, 604는 다른 에러들이 사용 중). 제거된 에러 코드들(EMPTY_REFRESH_HEADER 등) 때문에 생긴 번호 공백인 것 같은데, 향후 유지보수를 위해 번호를 재정리하는 것도 고려해볼 수 있습니다.

예를 들어:

  • 600번대를 인증 관련 에러로 통일
  • 번호를 순차적으로 재배치

기능적으로는 문제없지만 가독성과 관리 편의성 측면에서 개선 여지가 있습니다.


36-40: 에러 코드 번호 순서를 확인해주세요.

JWT 토큰 관련 에러 코드들이 잘 정리되었지만, INVALID_TOKEN_TYPE(601)과 INVALID_REFRESH_TYPE(605) 사이에 다른 코드들이 있어서 순서가 일관되지 않네요. 가독성을 위해 번호를 재정렬하는 걸 고려해보세요.

예시:

-INVALID_REFRESH_TYPE(605, HttpStatus.BAD_REQUEST.value(), "refresh token 타입이 유효하지 않습니다."),
-INVALID_TOKEN_TYPE(601, HttpStatus.UNAUTHORIZED.value(), "access token 타입이 유효하지 않습니다."),
+INVALID_TOKEN_TYPE(601, HttpStatus.UNAUTHORIZED.value(), "access token 타입이 유효하지 않습니다."),
+INVALID_REFRESH_TYPE(605, HttpStatus.BAD_REQUEST.value(), "refresh token 타입이 유효하지 않습니다."),

또는 601 다음에 602, 605 순으로 재정렬하는 것도 방법입니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f660ee and 66dee3a.

📒 Files selected for processing (4)
  • src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/handler/exception/CustomJsonAuthenticationFailureHandler.java (1 hunks)
  • src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/service/JwtService.java (3 hunks)
  • src/main/java/com/WhoIsRoom/WhoIs_Server/domain/user/service/UserService.java (1 hunks)
  • src/main/java/com/WhoIsRoom/WhoIs_Server/global/common/response/ErrorCode.java (2 hunks)
🔇 Additional comments (24)
src/main/java/com/WhoIsRoom/WhoIs_Server/domain/user/service/UserService.java (3)

59-64: 의미적으로 더 명확한 에러 코드로 개선되었습니다.

이메일 기반 사용자 조회 시 USER_MAIL_NOT_FOUND를 사용하는 것이 USER_NOT_FOUND보다 구체적이고 적절합니다.


61-61: 더 구체적인 에러 코드 적용, 좋습니다!

비밀번호 재설정 플로우에서 USER_NOT_FOUND 대신 USER_MAIL_NOT_FOUND를 사용하여 에러 메시지가 더 명확해졌습니다. 사용자 입장에서 "해당 이메일의 사용자를 찾을 수 없습니다"라는 메시지가 더 직관적이에요.


61-61: LGTM! 더 구체적인 에러 코드로 개선됐어요.

이메일 기반 조회 실패 시 USER_MAIL_NOT_FOUND를 사용하는 게 맥락상 더 명확하네요. 다른 메서드들은 userId 기반이라 USER_NOT_FOUND를 유지한 것도 합리적입니다.

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/handler/exception/CustomJsonAuthenticationFailureHandler.java (4)

31-41: 인증 실패 에러 매핑이 적절하게 개선되었습니다.

두 가지 변경사항 모두 PR 목표에 부합합니다:

  • UsernameNotFoundExceptionSECURITY_UNAUTHORIZED (401): 사용자 미존재 시 인증 실패로 처리
  • BadCredentialsExceptionINVALID_EMAIL_OR_PASSWORD (401): 자격 증명 오류를 더 명확하게 표현

모두 HTTP 401 상태로 통일되어 JWT 토큰 관련 에러와 일관성을 유지합니다.


34-41: 인증 실패 에러 코드 매핑 개선, 잘 적용됐어요!

두 가지 변경사항 모두 PR의 목표와 잘 맞아떨어집니다:

  1. UsernameNotFoundExceptionSECURITY_UNAUTHORIZED (401): 존재하지 않는 사용자는 인증 실패이므로 404가 아닌 401이 적절합니다.
  2. BadCredentialsExceptionINVALID_EMAIL_OR_PASSWORD (401): 잘못된 자격증명 역시 401로 처리하고, 네이밍도 "EMAIL_OR_PASSWORD"로 더 명확해졌네요.

34-36: 보안 측면에서 개선된 매핑이에요.

UsernameNotFoundExceptionSECURITY_UNAUTHORIZED로 매핑하여 사용자 존재 여부를 노출하지 않는 방식으로 변경되었습니다. 이는 계정 열거 공격(account enumeration)을 방지하는 좋은 접근이네요.


39-41: 더 명확한 에러 코드 네이밍으로 개선됐어요.

INVALID_ID_OR_PASSWORD에서 INVALID_EMAIL_OR_PASSWORD로 변경되어 이메일 기반 인증임이 더 명확해졌습니다.

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/auth/service/JwtService.java (6)

44-56: 토큰 타입 검증 에러 코드가 더 구체적으로 개선되었습니다.

INVALID_TOKEN_TYPE에서 INVALID_REFRESH_TYPE으로 변경하여 refresh 토큰 검증 컨텍스트를 명확히 표현합니다.


59-66: 토큰 재발급 로직의 에러 처리가 일관되게 개선되었습니다.

logout 메서드와 동일한 INVALID_REFRESH_TYPE 에러 코드를 사용하여 일관성을 유지합니다.


50-52: 리프레시 토큰 타입 검증 에러 코드 개선, 좋습니다!

INVALID_TOKEN_TYPE에서 INVALID_REFRESH_TYPE으로 변경하여 리프레시 토큰 타입 검증과 액세스 토큰 타입 검증을 구분하게 됐네요. 에러 코드가 더 구체적이고 명확해졌습니다.


62-64: 리프레시 토큰 타입 검증 에러 코드 개선, 일관성 있게 적용됐어요!

logout 메서드와 동일하게 INVALID_REFRESH_TYPE을 사용하여 일관성이 유지됩니다.


50-52: Refresh token 타입 검증 로직 개선됐어요.

INVALID_TOKEN_TYPE에서 INVALID_REFRESH_TYPE으로 변경되어 에러의 의도가 더 명확해졌습니다.


62-64: 일관된 에러 코드 사용으로 개선됐어요.

logout 메서드와 동일하게 INVALID_REFRESH_TYPE을 사용하여 일관성이 향상되었습니다.

src/main/java/com/WhoIsRoom/WhoIs_Server/global/common/response/ErrorCode.java (11)

21-21: 새로운 에러 코드가 적절하게 추가되었습니다.

USER_MAIL_NOT_FOUND는 이메일 기반 조회 실패를 명확하게 표현하며, HTTP 404 상태가 적절합니다.


36-40: 토큰 검증 에러 코드 구조가 개선되었습니다.

  • SECURITY_INVALID_TOKEN (602): 일반적인 토큰 검증 실패를 포괄하는 통합 에러 코드
  • INVALID_REFRESH_TYPE (605, 400): refresh 토큰 타입 불일치는 클라이언트 요청 오류
  • INVALID_TOKEN_TYPE (601, 401): access 토큰 타입 문제는 인증 오류

타입별 구분이 명확하고, HTTP 상태 코드 선택이 적절합니다.


47-50: JWT 토큰 검증 오류의 HTTP 상태 코드가 PR 목표에 맞게 수정되었습니다.

만료, 지원되지 않는 형식, 잘못된 구조, 유효하지 않은 시그니처 등 모든 토큰 검증 실패가 401로 통일되어 일관성이 향상되었습니다.


51-51: 자격 증명 오류 에러 코드가 명확하게 개선되었습니다.

INVALID_ID_OR_PASSWORD에서 INVALID_EMAIL_OR_PASSWORD로 변경하여 애플리케이션의 인증 방식(이메일 기반)을 명확히 반영합니다. HTTP 401 상태도 적절합니다.


52-52: 비밀번호 검증 오류의 HTTP 상태 변경을 확인하세요.

INVALID_PASSWORD를 401로 변경했는데, 이는 비밀번호 변경 시 기존 비밀번호 확인에 사용되는 에러입니다 (UserService.java line 72 참고).

고려사항:

  • 401 (UNAUTHORIZED): 인증 실패로 해석 가능
  • 400 (BAD_REQUEST): 입력 검증 실패로 해석 가능

비밀번호 변경은 이미 인증된 사용자가 수행하므로, 기존 비밀번호 불일치를 "인증 실패"로 볼지 "검증 실패"로 볼지는 애플리케이션의 보안 정책에 따라 다릅니다. 현재 선택(401)도 방어적 관점에서 합리적이나, 팀 내 논의를 권장합니다.


21-21: 새로운 에러 코드 추가, 명확한 의미 전달!

USER_MAIL_NOT_FOUND는 비밀번호 재설정 플로우에서 사용되며, "해당 이메일의 사용자를 찾을 수 없습니다"라는 구체적인 메시지로 사용자 경험을 개선합니다.


36-52: JWT 및 인증 관련 에러 HTTP 상태 코드 개선, PR 목표 달성!

토큰 및 인증 관련 에러들의 HTTP 상태를 400에서 401로 변경한 것이 PR의 핵심 목표와 일치합니다:

  • SECURITY_INVALID_TOKEN, EXPIRED_ACCESS_TOKEN, UNSUPPORTED_TOKEN_TYPE 등 토큰 관련 에러들이 401로 통일됐어요.
  • INVALID_EMAIL_CODE, EXPIRED_EMAIL_CODE 같은 인증 코드 검증 실패도 401로 변경.
  • INVALID_EMAIL_OR_PASSWORD (이전 INVALID_ID_OR_PASSWORD)도 401로 일관성 있게 처리.

전반적으로 인증/인가 실패는 401, 클라이언트 요청 오류는 400으로 구분하는 HTTP 시맨틱에 더 부합하게 됐습니다.


39-40: 리프레시/액세스 토큰 타입 에러의 상태 코드 차이 확인해보세요.

INVALID_REFRESH_TYPE (605)은 400을, INVALID_TOKEN_TYPE (601)은 401을 사용하고 있습니다. 둘 다 "잘못된 토큰 타입" 에러인데 상태 코드가 다른 이유가 명확한지 확인해보면 좋을 것 같아요.

의도한 설계라면 (예: 리프레시 토큰 타입 불일치는 클라이언트 오류 400, 액세스 토큰 타입 불일치는 인증 실패 401) 괜찮지만, 일관성을 위해 둘 다 401로 통일하는 것도 고려해볼 수 있습니다.


21-21: 새 에러 코드 추가가 적절해요.

USER_MAIL_NOT_FOUND가 추가되어 UserService.java의 이메일 기반 사용자 조회 실패를 더 명확하게 처리할 수 있게 되었습니다.


42-43: PR 목적에 맞게 인증 관련 에러들이 401로 잘 통일되었어요.

JWT 토큰 만료/검증 실패, 이메일 인증 코드 오류, 비밀번호 불일치 등 인증 관련 에러들이 모두 UNAUTHORIZED(401)로 변경되어 RESTful 관례에 부합하게 개선되었습니다.

Also applies to: 47-52


1-57: 제거된 에러 코드 사용 여부 확인 완료
전체 .java 파일에서 EMPTY_REFRESH_HEADER, LOGIN_FAILED, SECURITY_INVALID_REFRESH_TOKEN, INVALID_ID_OR_PASSWORD 참조가 없음을 확인했습니다.

@Shinjongyun Shinjongyun merged commit 06171b6 into develop Oct 3, 2025
2 checks passed
@Shinjongyun Shinjongyun changed the title [HotFix] #10 Jwt Token 응답 Http 상태코드 변경 [HotFix] jwt Token 응답 Http 상태코드 변경 Oct 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants