FIX : 가입 전용 요청 DTO와 클라이언트 오류 4xx 처리 - #108
Merged
Merged
Conversation
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%.
8 tasks
2 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🏫 관련 이슈
Closes #107
Refs #91 — 첫 항목(가입 전용 DTO)만 해소한다. 두 번째 항목(
/users구 경로 제거)은 순서 문제로 남긴다. 아래 참고.🏫 PR 타입
🏫 반영 브랜치
fix/signup-request-dto->main🏫 변경 사항
1. 가입 전용 요청 DTO
SignUpRequest(#91)POST /auth/register가 응답 DTO 인UserDto를 요청으로 받았다. 문제가 둘이었다.role,provider,emailVerified…)이 요청 계약에 노출 — 실제로role을 그대로 저장해 누구나 관리자가 됐다([ Auth ] 회원가입 요청의 role 을 신뢰해 누구나 관리자가 된다 #82)UserDto에 검증 어노테이션이 하나도 없어@Valid가 아무 일도 하지 않았다"1"gender: "X"Gender.valueOf)birthDate: "어제"role: "ADMIN"등서비스는 서버 결정 값을 여전히 명시적으로 고정한다. 요청 타입이 다시 넓어져도 결과가 바뀌지 않게.
프런트 화면은 이 엔드포인트를 호출하지 않는다(
PostRegister미사용).비밀번호 상한 64자는 BCrypt 가 72바이트 이후를 검사하지 않기 때문이다. 한글은 글자당 3바이트라
24자를 넘으면 뒷부분이 잘린다는 점을 주석에 남겼다.
2. 잘못 보낸 요청이 500 + 운영 알림이 되던 것 (#107) ⭐
이 핸들러는
ResponseEntityExceptionHandler를 상속하지 않고Exception최후 핸들러를 둔다.그래서 스프링이 원래 4xx 로 바꿔주던 예외까지 전부 500 + Slack 알림이 됐다. 실측(수정 전 5건 전부 500):
/policies/abc운영 문서가 경계하는 바로 그 유형이다 — "봇이 긁고 가면 알림이 울리고 진짜 장애가 묻힌다".
응답 메시지에 예외 원문은 넣지 않는다. 역직렬화 오류 메시지에는 내부 클래스명과 필드 구조가 들어 있다.
3.
@RateLimitAOP 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 에 남긴다.
🏫 테스트 결과
SignUpContractTest(7, 통합)ClientErrorStatusTest(5, 통합)RateLimitingAspectTest(6)UserServiceSignUpTest(재작성)