-
Notifications
You must be signed in to change notification settings - Fork 3
docs : Swagger 추가 및 리팩토링 #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough패키지 구조가 대대적으로 리팩토링되었으며, 인증 및 사용자 관련 DTO 클래스들이 request/response 패키지로 이동되었습니다. Swagger(OpenAPI) 어노테이션이 다양한 DTO와 컨트롤러에 추가되어 API 문서화가 강화되었습니다. JWT 유틸리티 구현체와 관련 설정 파일의 위치와 명칭도 변경되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthController
participant AuthService
participant JwtUtil
participant Redis
Client->>AuthController: POST /auth/signin (SigninRequest)
AuthController->>AuthService: signin(SigninRequest)
AuthService->>JwtUtil: createToken(...)
JwtUtil-->>AuthService: accessToken, refreshToken
AuthService->>Redis: Save refreshToken
AuthService-->>AuthController: SigninResponse(accessToken, refreshToken)
AuthController-->>Client: 200 OK (SigninResponse)
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (5)
src/main/java/org/ezcode/codetest/application/usermanagement/auth/service/AuthService.java (1)
118-120: 🛠️ Refactor suggestion서비스 계층의 HttpServletRequest 의존성 제거 제안
서비스 메서드가HttpServletRequest에 의존하고 있어 컨트롤러에서 헤더를 추출한 후 순수 토큰 문자열만 전달하도록 리팩토링이 필요합니다.다음과 같이 메서드 시그니처를 변경하면 좋겠습니다:
-public LogoutResponse logout(Long userId, HttpServletRequest request) { - String bearerToken = request.getHeader("Authorization"); +public LogoutResponse logout(Long userId, String bearerToken) { + // Authorization 헤더 추출은 컨트롤러에서 수행컨트롤러 쪽 변경 코드도 필요하시면 알려주세요.
src/main/java/org/ezcode/codetest/infrastructure/event/config/CustomHandShakeHandler.java (1)
31-38: 🛠️ Refactor suggestion
⚠️ Potential issue토큰 유효성 검증 누락
query파라미터에token=이 없거나 토큰이 비어 있을 경우tokenParam이null이 됩니다.jwtUtil.extractClaims(null)호출 시NullPointerException혹은ServerException이 발생하여 핸드셰이크가 실패합니다.+ if (!StringUtils.hasText(tokenParam)) { + throw new IllegalArgumentException("토큰이 전달되지 않았습니다."); + } + + // Bearer 접두사 제거 + tokenParam = jwtUtil.substringToken(tokenParam);적어도 널‧빈 문자열 체크와
Bearer접두사 제거를 추가해 주세요.src/main/java/org/ezcode/codetest/common/security/util/JwtUtil.java (1)
34-37: 🛠️ Refactor suggestion플랫폼 의존 문자셋 사용
secretKey.getBytes()는 기본 인코딩에 의존합니다. 예측 가능한 결과를 위해 UTF-8 명시가 필요합니다.- key = Keys.hmacShaKeyFor(secretKey.getBytes()); + key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java (1)
72-73: 🛠️ Refactor suggestion민감 정보 로깅 개선 필요
accessToken과refreshToken을 INFO 레벨로 출력하는 것은 보안 위험이 있으므로, 디버그 레벨로 변경하거나 로깅을 제거하세요.src/main/java/org/ezcode/codetest/common/security/config/SecurityConfig.java (1)
34-36:⚠️ Potential issueJWT 필터가 두 번 등록되고 있습니다
securityFilterChain안에서JwtFilter를addFilterBefore로 주입하면서 동시에 아래에FilterRegistrationBean으로 동일한 필터를/*경로에 다시 등록하고 있습니다.
이중 등록 시 필터가 두 번 실행되어 토큰 파싱·인증 로직이 중복 수행되고, 예외 처리/로깅 결과가 의도치 않게 두 번씩 발생할 수 있습니다.- @Bean - public FilterRegistrationBean<JwtFilter> jwtFilter() { - FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new JwtFilter(jwtUtil, redisTemplate)); - registrationBean.addUrlPatterns("/*"); - return registrationBean; - }
- 가장 간단한 해결: 위
FilterRegistrationBean메서드 자체를 제거하고, 현재addFilterBefore방식만 유지합니다.- 혹은,
FilterRegistrationBean하나만 두고securityFilterChain에서는addFilterBefore호출을 제거하는 방법도 있습니다.둘 중 하나로 정리하여 중복 실행을 방지해 주세요.
Also applies to: 81-84
🧹 Nitpick comments (14)
src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/SignupResponse.java (2)
5-9: 필드 null 방지 및 예시 값 추가 권장토큰은 필수 값이므로
@NotNull혹은@NonNull을 부여해 주면 런타임 NPE를 예방할 수 있습니다. 또한 Swagger 문서에 example 값을 제공하면 테스트가 수월해집니다.- @Schema(description = "생성된 token") - String token + @Schema(description = "생성된 token", example = "Bearer eyJhbGciOiJIUzI1NiJ9...") + @NonNull + String token
10-12: 정적 팩토리 메서드 불필요레코드의 생성자는 공개이므로
SignupResponse.from()은 래퍼 역할만 합니다. 사용처가 특별한 명명 규칙(DSL)을 요구하지 않는다면 제거하여 코드 간결성을 유지할 수 있습니다.src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/SigninResponse.java (1)
5-13: Swagger example 및 null 방어 로직 추가 제안
accessToken,refreshToken모두 필수이며 예시 값이 있으면 문서 가독성이 향상됩니다.- @Schema(description = "생성된 accessToken") - String accessToken, - @Schema(description = "생성된 refreshToken") - String refreshToken) { + @Schema(description = "생성된 accessToken", example = "Bearer eyJhbGciOiJIUzI1NiJ9...") + @NonNull + String accessToken, + @Schema(description = "생성된 refreshToken", example = "eyJhbGciOiJIUzI1NiJ9...") + @NonNull + String refreshToken) {src/main/java/org/ezcode/codetest/common/security/util/JwtUtil.java (3)
49-60: 토큰 접두사 정책 혼선
createToken은Bearer를 붙여 반환하지만createRefreshToken은 붙이지 않습니다. 또한extractClaims는 접두사 제거 없이 바로 파싱합니다. 호출 측에서 항상substringToken을 호출해야 하는데, 이를 문서화하거나 유틸 내부에서 자동으로 처리해 일관성을 확보하세요.
66-71: 예외 메시지 구체화
substringToken에서 토큰이 없을 때 단순"토큰이 없습니다"는 디버깅에 부족합니다. 어떤 형식이 기대되는지 명시하면 개발자 UX가 좋아집니다.- throw new ServerException("토큰이 없습니다"); + throw new ServerException("Authorization 헤더 또는 'Bearer ' 접두사가 없습니다");
96-99: 중복 로직 제거 가능
getExpiration과getRemainingTime이 유사한 계산을 수행합니다. 하나의 메서드로 합치거나 내부 재사용을 통해 유지보수성을 높일 수 있습니다.src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/RefreshTokenResponse.java (1)
7-7: 필드token에@Schema설명만 지정
일관성을 위해example속성을 추가하는 것을 고려하세요.@Schema(description = "생성된 refreshToken") -String token +String token; // example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java (1)
61-65: Redis 키 하드코딩 추출 권장
"RefreshToken:" + loginUser.getId()와 같은 키 패턴은 상수로 관리하면 오타 방지 및 재사용성이 높아집니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/ChangeUserPasswordRequest.java (1)
10-13: 검증 메시지 통일 제안
oldPassword필드는@NotBlank만 사용하고 메시지가 없습니다.newPassword와 동일하게 사용자 친화적 메시지를 넣으면 프론트엔드·문서 일관성이 높아집니다.- @NotBlank + @NotBlank(message = "기존 비밀번호는 공백일 수 없습니다.")src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SigninRequest.java (1)
17-26: 유효성 메시지 혼동 가능성
@NotBlank만 선언되어 있는데, 실제 오류 메시지는
공백 여부와 형식 오류를 구분해 주면 클라이언트 UX가 개선됩니다.- @NotBlank + @NotBlank(message = "이메일은 공백일 수 없습니다.")src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/OAuthResponse.java (1)
5-14: Schema 예시 값 추가 고려Swagger UI에서 토큰 예시가 있으면 테스트가 한층 수월합니다.
example속성을 추가해 보세요.- @Schema(description = "accessToken") + @Schema(description = "accessToken", example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...")동일하게
refreshToken도 적용하면 문서 완성도가 높아집니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserInfoResponse.java (1)
44-57: 빌더 파라미터 순서 가독성생성자 파라미터 순서가 필드 선언 순서와 달라 추후 리팩터링 시 혼동을 줄 수 있습니다.
@Builder사용 시에도 인자 순서를 맞추면 IDE 자동완성·리뷰 난이도가 내려갑니다. 큰 문제는 아니나 다음 수정 시 참고해 주세요.src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SignupRequest.java (1)
47-48: age 필드에 음수 방지 검증 추가 고려
선택 입력 필드이지만 음수 값을 방지하려면@Min(0)등을 추가하는 것을 제안합니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (1)
23-27: getProviderId 메서드 Null 안전성 검토 제안
attributes.get("sub")가null일 경우 NPE가 발생할 수 있습니다. Optional 처리나 예외 메시지를 추가 검토해주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (33)
src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SigninRequest.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SignupRequest.java(2 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/OAuthResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/RefreshTokenResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/SigninResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/SignupResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signin/RefreshTokenResponse.java(0 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signin/SigninResponse.java(0 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signup/SignupResponse.java(0 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/port/JwtUtil.java(0 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/auth/service/AuthService.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/ChangeUserPasswordRequest.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/ModifyUserInfoRequest.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/ChangeUserPasswordResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java(2 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/LogoutResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/SimpleUserInfoResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserInfoResponse.java(1 hunks)src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/WithdrawUserResponse.java(1 hunks)src/main/java/org/ezcode/codetest/common/annotation/Auth.java(0 hunks)src/main/java/org/ezcode/codetest/common/security/config/SecurityConfig.java(4 hunks)src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java(2 hunks)src/main/java/org/ezcode/codetest/common/security/util/ExceptionHandlingFilter.java(1 hunks)src/main/java/org/ezcode/codetest/common/security/util/JwtFilter.java(3 hunks)src/main/java/org/ezcode/codetest/common/security/util/JwtUtil.java(2 hunks)src/main/java/org/ezcode/codetest/common/security/util/PasswordEncoder.java(1 hunks)src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java(1 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/config/CustomHandShakeHandler.java(3 hunks)src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java(2 hunks)src/main/java/org/ezcode/codetest/infrastructure/security/config/FilterConfig.java(0 hunks)src/main/java/org/ezcode/codetest/infrastructure/security/config/WebConfig.java(0 hunks)src/main/java/org/ezcode/codetest/presentation/usermanagement/AuthController.java(3 hunks)src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java(3 hunks)
💤 Files with no reviewable changes (7)
- src/main/java/org/ezcode/codetest/infrastructure/security/config/FilterConfig.java
- src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signup/SignupResponse.java
- src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signin/SigninResponse.java
- src/main/java/org/ezcode/codetest/common/annotation/Auth.java
- src/main/java/org/ezcode/codetest/infrastructure/security/config/WebConfig.java
- src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/signin/RefreshTokenResponse.java
- src/main/java/org/ezcode/codetest/application/usermanagement/auth/port/JwtUtil.java
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/ChangeUserPasswordResponse.java (1)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/LogoutResponse.java (1)
Getter(6-15)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/LogoutResponse.java (1)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/ChangeUserPasswordResponse.java (1)
Getter(6-14)
src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/OAuthResponse.java (1)
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (1)
Schema(7-41)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (53)
src/main/java/org/ezcode/codetest/common/security/util/PasswordEncoder.java (1)
1-1: 패키지 경로 리팩토링 적절
PasswordEncoder가common.security.util로 이동되어 보안 유틸리티를 공통 영역에서 관리하도록 구조가 개선되었습니다. 스프링 컴포넌트 스캔 경로가 올바르게 설정되었는지 확인하세요.src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java (1)
7-7:Details
✅ Verification successful
Import 경로 일관성 확인 필요
PasswordEncoder의 패키지 경로가common.security.util로 업데이트 되었습니다. 코드베이스 전반에서 이전infrastructure.security.jwt패키지 참조가 남아있지 않은지 검토해주세요.
🏁 Script executed:
#!/bin/bash # 잔여 참조 검색 rg "org\\.ezcode\\.codetest\\.infrastructure\\.security\\.jwt" -nLength of output: 62
추가 검증을 위해 전체
infrastructure패키지 참조 여부를 확인해주세요:
🏁 Script executed:
#!/bin/bash # 전체 infrastructure 패키지 참조 검색 rg "org\\.ezcode\\.codetest\\.infrastructure" -nLength of output: 15045
Import 경로 일관성 확인 완료
common.security.util.PasswordEncoder로 패키지가 변경되었으며, 기존org.ezcode.codetest.infrastructure.security.jwt참조는 코드베이스에 더 이상 존재하지 않음을 확인했습니다.src/main/java/org/ezcode/codetest/common/security/util/ExceptionHandlingFilter.java (1)
1-1: 패키지 경로 리팩토링 확인됨
infrastructure.security.jwt에서common.security.util로 이동한 구조가 보안 유틸리티의 공통 레이어로 옮겨진 의도를 잘 반영합니다.src/main/java/org/ezcode/codetest/application/usermanagement/auth/service/AuthService.java (3)
5-9: DTO import 경로 업데이트 적절
SigninRequest,SignupRequest등 요청/응답 DTO가.request및.response패키지로 분리된 구조를 정확히 반영하고 있습니다.
16-16: JwtUtil import 경로 변경 적절
JwtUtilImpl에서common.security.util.JwtUtil로 전환된 내용이 일관되게 적용되었습니다.
32-32: 의존성 주입된 JwtUtil 사용 변경 적절
필드 주입된JwtUtil타입이 새 위치에서 올바르게 DI 되고 있습니다.src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java (3)
3-3: JwtUtil import 변경 적절
JwtUtilImpl에서common.security.util.JwtUtil로 전환된 import가 일관되게 적용되었습니다.
18-18: 의존성 주입된 JwtUtil 필드 변경 적절
새 패키지의JwtUtil이@RequiredArgsConstructor를 통해 주입되고 있습니다.
3-18:Details
✅ Verification successful
JwtUtil Bean 등록 여부 검증 필요
새로 이동된JwtUtil클래스가 Spring Bean으로 등록되어야 정상 주입됩니다.
🏁 Script executed:
#!/bin/bash # JwtUtil이 @Component 또는 @Service 어노테이션으로 등록되어 있는지 확인 rg -n '@Component|@Service' src/main/java/org/ezcode/codetest/common/security/util/JwtUtil.javaLength of output: 111
JwtUtil 스프링 Bean 등록 확인 완료
JwtUtil 클래스에@Component어노테이션이 선언되어 있어 스프링 Bean으로 정상 등록되며, 주입에 문제가 없습니다.src/main/java/org/ezcode/codetest/common/security/util/JwtFilter.java (3)
1-1: 패키지 경로 리팩토링 확인됨
infrastructure.security.jwt에서common.security.util로 이동한 패키지 선언이 의도대로 업데이트되었습니다.
31-31: JwtUtil 의존성 변경 적절
JwtUtilImpl에서JwtUtil로 필드 타입이 변경되어 토큰 처리 로직이 새 유틸로 일원화되었습니다.
45-51: 토큰 처리 로직 연동 확인
substringToken과extractClaims호출부가 새JwtUtil인터페이스로 잘 마이그레이션되었습니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/ChangeUserPasswordResponse.java (3)
3-3: Swagger Schema import 추가
io.swagger.v3.oas.annotations.media.Schemaimport가 잘 추가되어 있습니다.
7-7: 클래스 레벨 @Schema 주석 추가
DTO 설명을 위한@Schema(description = "비밀번호 변경 응답 DTO")가 일관성 있게 적용되었습니다.
9-9: 필드 레벨 @Schema 예시 추가
message필드에 대한 설명과 예시가 Swagger 문서에 잘 반영되어 있습니다.src/main/java/org/ezcode/codetest/infrastructure/event/config/CustomHandShakeHandler.java (1)
19-19: 의존성 명칭 변경 👍
JwtUtilImpl→JwtUtil로의 의존성 교체가 일관성 있게 반영되었습니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/WithdrawUserResponse.java (1)
5-9: Swagger 예시 👍예시 값이 포함되어 API 문서 가독성이 향상되었습니다. 추가 조치 필요 없어 보입니다.
src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/LogoutResponse.java (3)
3-3:io.swagger.v3.oas.annotations.media.Schema임포트 추가 승인
Swagger 어노테이션 사용을 위해 필요한 임포트입니다.
7-7: 클래스 레벨@Schema어노테이션 적용 승인
DTO 설명으로 "로그아웃 응답 DTO"가 명확하게 정의되었습니다.
9-9: 필드 레벨@Schema어노테이션 적용 승인
message필드의 설명과 예제 값이 적절하게 지정되었습니다.src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/response/RefreshTokenResponse.java (3)
3-3:io.swagger.v3.oas.annotations.media.Schema임포트 추가 승인
OpenAPI 메타데이터를 위해 필요한 임포트입니다.
5-5: 레코드 클래스 레벨@Schema적절성 확인
"refreshToken 응답"으로 응답 DTO 의미가 잘 전달됩니다.
10-13: 정적 팩토리 메서드from구현 승인
토큰에서 DTO로 변환하는 일관된 생성 방식을 제공합니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/ModifyUserInfoRequest.java (3)
3-3:io.swagger.v3.oas.annotations.media.Schema임포트 추가 승인
모든 필드에 대한 API 문서화가 가능해집니다.
5-5: 레코드 클래스 레벨@Schema적용 승인
"회원 정보 변경 요청"이 명확하게 표현되었습니다.
7-23: 필드 단위@Schema어노테이션 적용 승인
모든 필드에 설명과 예제가 일관성 있게 지정되어 있습니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/SimpleUserInfoResponse.java (3)
6-6:io.swagger.v3.oas.annotations.media.Schema임포트 추가 승인
Swagger 어노테이션을 사용하기 위한 적절한 임포트입니다.
11-11: 클래스 레벨@Schema어노테이션 적용 승인
"간단한 사용자 정보 응답 DTO" 설명이 명확합니다.
13-23: 필드 수준@Schema적용 승인
각 필드에 대한 설명과 예제가 적절히 지정되어 있습니다.src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java (4)
1-1: 패키지 경로 변경 확인
infrastructure.security.hander→common.security.hander로 이동하여 공통 모듈화가 잘 이루어졌습니다.
6-6:OAuthResponse임포트 경로 업데이트 승인
리팩토링된 DTO 패키지 구조를 올바르게 참조합니다.
10-10:JwtUtil인터페이스 의존성 주입으로 변경 승인
구체 구현 대신 인터페이스를 사용해 유연성을 확보했습니다.
31-37: 생성자 파라미터 타입 업데이트 승인
JwtUtilImpl→JwtUtil로 변경하여 인터페이스 기반 주입이 잘 적용되었습니다.src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SignupRequest.java (6)
15-15: 클래스 수준 Swagger @Schema 어노테이션 추가 확인
클래스에@Schema(description = "회원가입 요청")가 잘 추가되어 API 문서화가 강화되었습니다.
18-21: 이메일 필드에 유효성 및 문서화 적용
@NotBlank,@Schema가 적절히 선언되어 있으며, 메시지와 예시도 명확합니다.
23-28: 비밀번호 필드에 패턴 검증 및 문서화 적용
복잡도와 길이 조건을 모두 다루는@Pattern과@Schema가 적절합니다.
31-33: 패스워드 확인 필드 검증 로직 확인 필요
passwordConfirm에는@NotBlank만 적용되어 있습니다. 실제로 입력 값 일치 검증이 서비스 계층에서 수행되는지 확인해주세요.
36-39: 사용자 이름 필드 검증 및 문서화 적용
@NotBlank,@Size,@Schema가 잘 선언되어 있습니다.
41-44: 별명 필드 검증 및 문서화 적용
@NotBlank,@Size,@Schema가 일관되게 적용되어 있습니다.src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java (4)
5-8: 클래스 수준 Swagger @Schema 어노테이션 추가 확인
@Schema(description = "Google OAuth2 응답 처리 클래스")가 잘 적용되어 있습니다.
17-20: getProvider 메서드 Swagger 문서화
@Schema를 통해 반환값 명세가 명확해졌습니다.
30-33: getEmail 메서드 Swagger 문서화
@Schema덕분에 반환 형식과 예시가 잘 정의되었습니다.
36-39: getName 메서드 Swagger 문서화
문서화 어노테이션이 명확하게 적용되어 있습니다.src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java (6)
3-7: DTO 패키지 경로 업데이트 확인
ModifyUserInfoRequest,ChangeUserPasswordRequest,UserInfoResponse등 DTO import 경로가 새로운 구조로 잘 반영되었습니다.
19-20: Swagger @tag 및 @operation import/어노테이션 추가
클래스 레벨@Tag(name = "사용자 기본 기능", ...)가 적절히 선언되어 있습니다.Also applies to: 28-28
32-37: 내 정보 조회 API 문서화
@Operation(summary = "내 정보 조회", ...)가 잘 적용되었으며, ResponseEntity 빌드 로직도 문제 없습니다.
39-46: 내 정보 수정 API 문서화
@Operation이 적절히 추가되어 있으며, 유효성 검증 어노테이션(@Valid) 적용은modifyUserPassword에서만 필요한 부분으로 보입니다.
48-55: 비밀번호 변경 API 문서화
@Valid와@Operation이 올바르게 선언되어 있습니다.
58-65: 회원 탈퇴 API 문서화
@Operation(summary = "회원 탈퇴", ...)가 적용되어 있으며, 응답 타입도 맞습니다.src/main/java/org/ezcode/codetest/presentation/usermanagement/AuthController.java (4)
3-7: 인증 DTO 패키지 경로 업데이트 확인
SigninRequest,SignupRequest,SigninResponse,SignupResponse,RefreshTokenResponse의 import 경로가 새로운 패키지 구조를 잘 반영하고 있습니다.
18-20: Swagger @tag 및 @operation import/어노테이션 추가
클래스 레벨@Tag(name = "인증/인가", ...)와 각 메서드의@Operation이 적절히 선언되었습니다.Also applies to: 28-28
32-36: 회원가입 API 문서화
signup메서드에@Operation,@PostMapping("/auth/signup")가 잘 적용되어 있습니다.
38-42: 로그인 API 문서화
signin메서드 역시@Operation,@PostMapping("/auth/signin")이 올바르게 추가되었습니다.
| log.info("authUserEmail: {}, authUserID : {}", authUser.getEmail(), authUser.getId()); | ||
| return ResponseEntity.status(HttpStatus.OK).body(userService.getUserInfo(authUser)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PII 노출 방지: 로깅 레벨 조정 필요
authUser.getEmail(), authUser.getId()를 info 레벨로 로깅하고 있어 민감 정보가 외부에 노출될 수 있습니다. debug 레벨로 변경하거나 마스킹을 고려하세요.
🤖 Prompt for AI Agents
In
src/main/java/org/ezcode/codetest/presentation/usermanagement/UserController.java
around lines 35 to 37, the log statement outputs sensitive user information
(email and ID) at info level, risking PII exposure. Change the log level from
info to debug or mask the sensitive data before logging to prevent exposing
personal information in production logs.
| @Operation(summary = "토큰 재발급", description = "리프레시 토큰을 이용하여 새로운 액세스 토큰을 발급합니다.") | ||
| @PostMapping("/auth/refresh") | ||
| public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) { | ||
| return ResponseEntity.status(HttpStatus.OK).body(authService.refreshToken(request)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
서비스 계층 분리: 토큰 재발급 요청 객체 제한 필요
refresh 메서드도 HttpServletRequest 대신 토큰 문자열만 추출해 서비스로 전달하도록 수정해야 합니다.
-public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) {
- return ResponseEntity.status(HttpStatus.OK)
- .body(authService.refreshToken(request));
-}
+public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) {
+ String refreshToken = Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION))
+ .map(h -> h.replace("Bearer ", ""))
+ .orElseThrow(() -> new IllegalArgumentException("Authorization 헤더가 없습니다."));
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(authService.refreshToken(refreshToken));
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Operation(summary = "토큰 재발급", description = "리프레시 토큰을 이용하여 새로운 액세스 토큰을 발급합니다.") | |
| @PostMapping("/auth/refresh") | |
| public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) { | |
| return ResponseEntity.status(HttpStatus.OK).body(authService.refreshToken(request)); | |
| } | |
| @Operation(summary = "토큰 재발급", description = "리프레시 토큰을 이용하여 새로운 액세스 토큰을 발급합니다.") | |
| @PostMapping("/auth/refresh") | |
| public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) { | |
| String refreshToken = Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION)) | |
| .map(h -> h.replace("Bearer ", "")) | |
| .orElseThrow(() -> new IllegalArgumentException("Authorization 헤더가 없습니다.")); | |
| return ResponseEntity.status(HttpStatus.OK) | |
| .body(authService.refreshToken(refreshToken)); | |
| } |
🤖 Prompt for AI Agents
In
src/main/java/org/ezcode/codetest/presentation/usermanagement/AuthController.java
around lines 52 to 56, the refresh method currently passes the entire
HttpServletRequest to the service layer. Modify this method to extract only the
token string from the HttpServletRequest within the controller and pass that
token string to the authService.refreshToken method, ensuring the service layer
receives only the necessary token data.
| @Operation(summary = "로그아웃", description = "현재 로그인된 사용자의 로그아웃을 수행합니다.") | ||
| @PostMapping("/auth/logout") | ||
| public ResponseEntity<LogoutResponse> logout( | ||
| @AuthenticationPrincipal AuthUser authUser, | ||
| HttpServletRequest request) { | ||
| return ResponseEntity.status(HttpStatus.OK).body(authService.logout(authUser.getId(), request)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
서비스 계층 분리: logout 요청 객체 제한 필요
컨트롤러에서 HttpServletRequest 전체를 서비스로 전달하고 있습니다. 요청 헤더에서 토큰만 추출해 String으로 전달하도록 메서드 시그니처를 분리하세요.
-public ResponseEntity<LogoutResponse> logout(
- @AuthenticationPrincipal AuthUser authUser,
- HttpServletRequest request) {
- return ResponseEntity.status(HttpStatus.OK)
- .body(authService.logout(authUser.getId(), request));
-}
+public ResponseEntity<LogoutResponse> logout(
+ @AuthenticationPrincipal AuthUser authUser,
+ HttpServletRequest request) {
+ String refreshToken = Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION))
+ .map(h -> h.replace("Bearer ", ""))
+ .orElseThrow(() -> new IllegalArgumentException("Authorization 헤더가 없습니다."));
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(authService.logout(authUser.getId(), refreshToken));
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @Operation(summary = "로그아웃", description = "현재 로그인된 사용자의 로그아웃을 수행합니다.") | |
| @PostMapping("/auth/logout") | |
| public ResponseEntity<LogoutResponse> logout( | |
| @AuthenticationPrincipal AuthUser authUser, | |
| HttpServletRequest request) { | |
| return ResponseEntity.status(HttpStatus.OK).body(authService.logout(authUser.getId(), request)); | |
| @Operation(summary = "로그아웃", description = "현재 로그인된 사용자의 로그아웃을 수행합니다.") | |
| @PostMapping("/auth/logout") | |
| public ResponseEntity<LogoutResponse> logout( | |
| @AuthenticationPrincipal AuthUser authUser, | |
| HttpServletRequest request) { | |
| String refreshToken = Optional.ofNullable(request.getHeader(HttpHeaders.AUTHORIZATION)) | |
| .map(h -> h.replace("Bearer ", "")) | |
| .orElseThrow(() -> new IllegalArgumentException("Authorization 헤더가 없습니다.")); | |
| return ResponseEntity.status(HttpStatus.OK) | |
| .body(authService.logout(authUser.getId(), refreshToken)); | |
| } |
🤖 Prompt for AI Agents
In
src/main/java/org/ezcode/codetest/presentation/usermanagement/AuthController.java
around lines 44 to 49, the logout method currently passes the entire
HttpServletRequest to the service layer. Refactor this by extracting only the
token string from the request headers in the controller, then modify the service
method signature to accept the user ID and the token string instead of the full
HttpServletRequest object.
|
Docs : |
작업 내용
트러블 슈팅
@Transactional이 적용되지 않음this.→AopProxyUtils.사용)해결해야 할 문제
코드 리뷰 전 확인 체크리스트
type :)Summary by CodeRabbit
문서화
리팩터
기타