Skip to content

FIX : 가입 전용 요청 DTO와 클라이언트 오류 4xx 처리 - #108

Merged
RosieOh merged 1 commit into
mainfrom
fix/signup-request-dto
Sep 22, 2026
Merged

RosieOh merged 1 commit into
mainfrom
fix/signup-request-dto

Conversation

@RosieOh

@RosieOh RosieOh commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

🏫 관련 이슈

Closes #107
Refs #91 — 첫 항목(가입 전용 DTO)만 해소한다. 두 번째 항목(/users 구 경로 제거)은 순서 문제로 남긴다. 아래 참고.

🏫 PR 타입

  • 기능 추가
  • 기능 수정
  • 기능 삭제
  • 버그 수정
  • 의존성, 환경 변수, 빌드 관련 코드 업데이트

🏫 반영 브랜치

fix/signup-request-dto -> main

🏫 변경 사항

1. 가입 전용 요청 DTO SignUpRequest (#91)

POST /auth/register 가 응답 DTO 인 UserDto 를 요청으로 받았다. 문제가 둘이었다.

요청 이전 이후
빈 이메일 / 형식이 틀린 이메일 가입됨 400
비밀번호 "1" 가입됨 400 (8~64자)
이름 없음 500 (DB NOT NULL) 400
gender: "X" 500 (Gender.valueOf) 400
birthDate: "어제" 500 400
role: "ADMIN" 등 서비스에서 무시 받을 필드가 없어 버려짐

서비스는 서버 결정 값을 여전히 명시적으로 고정한다. 요청 타입이 다시 넓어져도 결과가 바뀌지 않게.
프런트 화면은 이 엔드포인트를 호출하지 않는다(PostRegister 미사용).

비밀번호 상한 64자는 BCrypt 가 72바이트 이후를 검사하지 않기 때문이다. 한글은 글자당 3바이트라
24자를 넘으면 뒷부분이 잘린다는 점을 주석에 남겼다.

2. 잘못 보낸 요청이 500 + 운영 알림이 되던 것 (#107) ⭐

이 핸들러는 ResponseEntityExceptionHandler 를 상속하지 않고 Exception 최후 핸들러를 둔다.
그래서 스프링이 원래 4xx 로 바꿔주던 예외까지 전부 500 + Slack 알림이 됐다. 실측(수정 전 5건 전부 500):

요청 이전 이후
깨진 JSON 500 🔔 400
필수 파라미터 누락 500 🔔 400
경로 변수 타입 불일치 /policies/abc 500 🔔 400
지원하지 않는 메서드 500 🔔 405
지원하지 않는 Content-Type 500 🔔 415
업로드 크기 초과 500 🔔 413

운영 문서가 경계하는 바로 그 유형이다 — "봇이 긁고 가면 알림이 울리고 진짜 장애가 묻힌다".
응답 메시지에 예외 원문은 넣지 않는다. 역직렬화 오류 메시지에는 내부 클래스명과 필드 구조가 들어 있다.

3. @RateLimit AOP fail-open (#107)

RateLimitingAspect 가 DataAccessException 만 잡아서, 그 밖의 런타임 실패는 500 이 되고
로그인·가입·인증코드·챗봇이 한꺼번에 멈췄다. RateLimitInterceptor 에서 같은 결함을 고쳤는데(#87)
여기는 남아 있었다. 가입 통합 테스트가 이것 때문에 500 으로 떨어져서 드러났다.

기존 AccessControlContractTest 는 가입 흐름 경로를 "401/403 이 아니다" 로만 확인해 이 500 을 놓치고 있었다.
fail-open 범위를 넓히면서 대상 메서드가 던진 예외는 삼키지 않는다 — 테스트로 고정했다.

🏫 #91 의 두 번째 항목을 넣지 않은 이유

/users/{userId}/location 을 /users/me/location 으로 바꾸려면 프런트가 먼저 바뀌어야 한다.
그런데 운영 백엔드는 배포가 막혀(#94) 옛 코드 그대로라 /users/me/* 가 운영에 없다.
프런트 저장소에는 배포 워크플로가 없어 배포 방식을 저장소에서 확인할 수 없고, 독립적으로 나간다고 봐야 한다.
지금 프런트를 바꾸면 운영에서 위치 갱신이 깨진다.

순서가 강제된다: 백엔드 배포(#94) → 프런트 전환 → 구 경로 제거. #91 에 남긴다.

🏫 테스트 결과

486 tests, 0 failures   (기존 471 → +15)
전체 라인 커버리지 38.6% → 39.1%
신규/변경 테스트 고정하는 계약
SignUpContractTest (7, 통합) 실제 JSON 에 role·provider·emailVerified 를 넣어도 서버 값으로 저장 / 잘못된 가입 6종이 400 이고 계정이 생기지 않음
ClientErrorStatusTest (5, 통합) 400·405·415 이고 운영 알림이 울리지 않음
RateLimitingAspectTest (6) Redis 장애·비-DataAccess 실패에도 통과 / 대상 메서드 예외는 그대로 / 계정·IP 기준 키
UserServiceSignUpTest (재작성) SignUpRequest 기준으로 서버 결정 값 고정

1) 가입 요청을 SignUpRequest 로 분리했다 (#91 의 첫 항목).

   POST /auth/register 가 응답 DTO 인 UserDto 를 그대로 받았다. 서버가 정할 값(role,
   provider, emailVerified …)이 요청 계약에 노출돼 있었고(#82), UserDto 에 검증
   어노테이션이 없어 @Valid 가 아무 일도 하지 않았다. 빈 이메일·형식이 틀린 이메일·
   한 글자 비밀번호로 가입됐고, 이름이 없으면 DB 제약에서, 성별 값이 틀리면
   Gender.valueOf 에서 500 이었다.

   가입자가 정할 수 있는 값만 두고 검증을 붙였다. 요청에 role 등을 넣어도 받을 필드가
   없어 버려진다. 서비스는 서버 결정 값을 여전히 명시적으로 고정해, 요청 타입이 다시
   넓어져도 결과가 바뀌지 않게 했다. 프런트 화면은 이 엔드포인트를 호출하지 않는다.

2) 잘못 보낸 요청이 500 + 운영 알림이 되던 것을 4xx 로.

   이 핸들러는 ResponseEntityExceptionHandler 를 상속하지 않고 Exception 최후 핸들러를
   둔다. 그래서 스프링이 원래 4xx 로 바꿔주던 예외까지 전부 500 이 되고 Slack 알림이
   울렸다. 실측으로 확인했다(수정 전 5건 전부 500).

     깨진 JSON / 필수 파라미터 누락 / 타입 불일치     → 400
     지원하지 않는 메서드                              → 405
     지원하지 않는 Content-Type                        → 415
     업로드 크기 초과                                  → 413

   응답 메시지에 예외 원문은 넣지 않는다(역직렬화 오류에 내부 클래스명이 들어 있다).

3) @ratelimit AOP 가 모든 런타임 실패에 fail-open 하도록.

   DataAccessException 만 잡아서, 그 밖의 실패는 500 이 되고 로그인·가입·인증코드·챗봇이
   한꺼번에 멈췄다. RateLimitInterceptor 에서 같은 결함을 고쳤는데(#87) 여기는 남아
   있었다. 회원가입 통합 테스트가 이것 때문에 500 으로 떨어져 드러났다.
   대상 메서드가 던진 예외는 삼키지 않는다(테스트로 고정).

#91 의 두 번째 항목(/users 구 경로 제거)은 이 PR 에 없다. 운영 백엔드가 배포되지 않아
/users/me/* 가 운영에 없는 상태에서 프런트를 먼저 바꾸면 위치 갱신이 깨진다.
순서(백엔드 배포 → 프런트 전환 → 구 경로 제거)를 #91 에 남긴다.

486 tests, 0 failures. 전체 라인 커버리지 39.1%.
@RosieOh
RosieOh merged commit 13e35f3 into main Sep 22, 2026
7 checks passed
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.

[ Core ] 잘못 보낸 요청이 500 과 운영 알림이 되고, 가입 요청 검증이 동작하지 않는다

1 participant