Skip to content

Conversation

@minjee2758
Copy link
Collaborator

@minjee2758 minjee2758 commented Jun 12, 2025

작업 내용

  • Swagger 추가
  • JwtUtil interface로 구현 삭제
  • jwt 패키지명을 util로 변경
  • security 패키지 위치를 infra에서 common으로 변경

트러블 슈팅

  • 구현 중 마주한 문제와 해결 방법을 기술해주세요.
  • 예)
    • 문제: @Transactional이 적용되지 않음
    • 해결: 메서드 호출 방식 변경 (this.AopProxyUtils. 사용)

해결해야 할 문제

  • Logout 리팩토링 필요함
    • HttpServeletRequest를 컨트롤러에서 처리 후, String으로 service에 전달해야함

코드 리뷰 전 확인 체크리스트

  • 불필요한 콘솔 로그, 주석 제거
  • 커밋 메시지 컨벤션 준수 (type : )
  • 기능 정상 동작 확인

Summary by CodeRabbit

  • 문서화

    • 모든 인증 및 사용자 관련 API에 Swagger(OpenAPI) 문서화 어노테이션(@Schema, @tag, @operation 등)이 추가되어 API 명세가 한글 설명과 예시와 함께 개선되었습니다.
    • 회원가입, 로그인, 로그아웃, 토큰 재발급, 사용자 정보 조회/수정/비밀번호 변경/탈퇴 등 모든 주요 엔드포인트에 상세 설명이 제공됩니다.
  • 리팩터

    • 인증 및 사용자 관련 DTO 패키지 구조가 request/response로 정리되어 가독성과 유지보수가 향상되었습니다.
    • 일부 엔드포인트 경로가 /auth/로 통일되었습니다.
  • 기타

    • 내부 보안 및 JWT 유틸리티 클래스 구조가 변경되어 보안 구성의 일관성이 강화되었습니다.

@minjee2758 minjee2758 self-assigned this Jun 12, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 12, 2025

Walkthrough

패키지 구조가 대대적으로 리팩토링되었으며, 인증 및 사용자 관련 DTO 클래스들이 request/response 패키지로 이동되었습니다. Swagger(OpenAPI) 어노테이션이 다양한 DTO와 컨트롤러에 추가되어 API 문서화가 강화되었습니다. JWT 유틸리티 구현체와 관련 설정 파일의 위치와 명칭도 변경되었습니다.

Changes

파일/경로 그룹 변경 요약
.../auth/dto/request/SigninRequest.java
.../auth/dto/request/SignupRequest.java
SigninRequest, SignupRequest 클래스 패키지 이동 및 Swagger @Schema 어노테이션 추가, 필드별 예시 및 설명 추가
.../auth/dto/response/OAuthResponse.java OAuthResponse 패키지 이동 및 @Schema 어노테이션 추가
.../auth/dto/response/RefreshTokenResponse.java
.../auth/dto/response/SigninResponse.java
.../auth/dto/response/SignupResponse.java
RefreshTokenResponse, SigninResponse, SignupResponse 신규 record 추가 및 @Schema 어노테이션, 정적 팩토리 메서드 추가
.../auth/dto/signin/RefreshTokenResponse.java
.../auth/dto/signin/SigninResponse.java
.../auth/dto/signup/SignupResponse.java
기존 RefreshTokenResponse, SigninResponse, SignupResponse record 파일 삭제(패키지 이동 및 @Schema 추가된 파일로 대체)
.../auth/port/JwtUtil.java JwtUtil 인터페이스 삭제(구현체로 대체)
.../auth/service/AuthService.java DTO, JwtUtil import 경로 변경(패키지 리팩토링 반영)
.../user/dto/request/ChangeUserPasswordRequest.java
.../user/dto/request/ModifyUserInfoRequest.java
ChangeUserPasswordRequest, ModifyUserInfoRequest record에 Swagger @Schema 어노테이션 및 필드별 예시/설명 추가
.../user/dto/response/ChangeUserPasswordResponse.java
.../user/dto/response/LogoutResponse.java
.../user/dto/response/SimpleUserInfoResponse.java
.../user/dto/response/UserInfoResponse.java
.../user/dto/response/WithdrawUserResponse.java
.../user/dto/response/GoogleOAuth2Response.java
Swagger @Schema 어노테이션 추가, 각 필드별 예시 및 설명 추가
.../common/annotation/Auth.java Auth 커스텀 어노테이션 삭제
.../common/security/config/SecurityConfig.java 패키지 이동, JwtUtilImpl → JwtUtil로 교체, 허용 경로 수정, jwtFilter Bean 등록 메서드 추가
.../common/security/hander/CustomSuccessHandler.java 패키지 이동, JwtUtilImpl → JwtUtil로 생성자 파라미터 및 필드 타입 변경
.../common/security/util/ExceptionHandlingFilter.java
.../common/security/util/PasswordEncoder.java
패키지 이동만 수행
.../common/security/util/JwtFilter.java 패키지 이동, JwtUtilImpl → JwtUtil로 필드 및 사용부 변경
.../common/security/util/JwtUtil.java JwtUtilImpl → JwtUtil로 클래스명 변경, 패키지 이동, 인터페이스 구현 제거
.../domain/user/service/UserDomainService.java PasswordEncoder import 경로 변경(패키지 이동 반영)
.../infrastructure/event/config/CustomHandShakeHandler.java
.../infrastructure/event/config/WebSocketConfig.java
JwtUtilImpl → JwtUtil로 필드 타입 및 사용부 변경
.../infrastructure/security/config/FilterConfig.java
.../infrastructure/security/config/WebConfig.java
FilterConfig, WebConfig 클래스 삭제(필터 등록 및 MVC 설정 관련)
.../presentation/usermanagement/AuthController.java DTO import 경로 정리, Swagger @tag@operation 어노테이션 추가, 모든 엔드포인트 경로 /auth/로 통일
.../presentation/usermanagement/UserController.java Swagger @tag@operation 어노테이션 추가, API 문서화 강화

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)
Loading

Possibly related PRs

Suggested labels

documentation

Suggested reviewers

  • pokerbearkr
  • Kimminu7
  • chat26666

Poem

🐇
Swagger 구름이 두둥실,
DTO들이 새 옷을 입었네.
패키지 이사도 척척,
필드마다 예시와 설명이 반짝!
인증 API도 한층 더 친절해진 오늘,
토끼는 기쁘게 깡충깡충!
🥕

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 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=이 없거나 토큰이 비어 있을 경우 tokenParamnull이 됩니다. 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

민감 정보 로깅 개선 필요
accessTokenrefreshToken을 INFO 레벨로 출력하는 것은 보안 위험이 있으므로, 디버그 레벨로 변경하거나 로깅을 제거하세요.

src/main/java/org/ezcode/codetest/common/security/config/SecurityConfig.java (1)

34-36: ⚠️ Potential issue

JWT 필터가 두 번 등록되고 있습니다

securityFilterChain 안에서 JwtFilteraddFilterBefore로 주입하면서 동시에 아래에 FilterRegistrationBean으로 동일한 필터를 /* 경로에 다시 등록하고 있습니다.
이중 등록 시 필터가 두 번 실행되어 토큰 파싱·인증 로직이 중복 수행되고, 예외 처리/로깅 결과가 의도치 않게 두 번씩 발생할 수 있습니다.

- @Bean
- public FilterRegistrationBean<JwtFilter> jwtFilter() {
-     FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();
-     registrationBean.setFilter(new JwtFilter(jwtUtil, redisTemplate));
-     registrationBean.addUrlPatterns("/*");
-     return registrationBean;
- }
  1. 가장 간단한 해결: 위 FilterRegistrationBean 메서드 자체를 제거하고, 현재 addFilterBefore 방식만 유지합니다.
  2. 혹은, 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: 토큰 접두사 정책 혼선

createTokenBearer 를 붙여 반환하지만 createRefreshToken은 붙이지 않습니다. 또한 extractClaims는 접두사 제거 없이 바로 파싱합니다. 호출 측에서 항상 substringToken을 호출해야 하는데, 이를 문서화하거나 유틸 내부에서 자동으로 처리해 일관성을 확보하세요.


66-71: 예외 메시지 구체화

substringToken에서 토큰이 없을 때 단순 "토큰이 없습니다" 는 디버깅에 부족합니다. 어떤 형식이 기대되는지 명시하면 개발자 UX가 좋아집니다.

-		throw new ServerException("토큰이 없습니다");
+		throw new ServerException("Authorization 헤더 또는 'Bearer ' 접두사가 없습니다");

96-99: 중복 로직 제거 가능

getExpirationgetRemainingTime이 유사한 계산을 수행합니다. 하나의 메서드로 합치거나 내부 재사용을 통해 유지보수성을 높일 수 있습니다.

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: 유효성 메시지 혼동 가능성

email 필드에는 @NotBlank만 선언되어 있는데, 실제 오류 메시지는 @Email에만 정의되어 있어 “공백”과 “형식 오류” 케이스가 같은 메시지로 반환될 수 있습니다.
공백 여부와 형식 오류를 구분해 주면 클라이언트 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

📥 Commits

Reviewing files that changed from the base of the PR and between 359c4e1 and f4fbe74.

📒 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: 패키지 경로 리팩토링 적절
PasswordEncodercommon.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" -n

Length of output: 62


추가 검증을 위해 전체 infrastructure 패키지 참조 여부를 확인해주세요:


🏁 Script executed:

#!/bin/bash
# 전체 infrastructure 패키지 참조 검색
rg "org\\.ezcode\\.codetest\\.infrastructure" -n

Length 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.java

Length 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: 토큰 처리 로직 연동 확인
substringTokenextractClaims 호출부가 새 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.Schema import가 잘 추가되어 있습니다.


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: 의존성 명칭 변경 👍

JwtUtilImplJwtUtil로의 의존성 교체가 일관성 있게 반영되었습니다.

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.handercommon.security.hander로 이동하여 공통 모듈화가 잘 이루어졌습니다.


6-6: OAuthResponse 임포트 경로 업데이트 승인
리팩토링된 DTO 패키지 구조를 올바르게 참조합니다.


10-10: JwtUtil 인터페이스 의존성 주입으로 변경 승인
구체 구현 대신 인터페이스를 사용해 유연성을 확보했습니다.


31-37: 생성자 파라미터 타입 업데이트 승인
JwtUtilImplJwtUtil로 변경하여 인터페이스 기반 주입이 잘 적용되었습니다.

src/main/java/org/ezcode/codetest/application/usermanagement/auth/dto/request/SignupRequest.java (6)

15-15: 클래스 수준 Swagger @Schema 어노테이션 추가 확인
클래스에 @Schema(description = "회원가입 요청")가 잘 추가되어 API 문서화가 강화되었습니다.


18-21: 이메일 필드에 유효성 및 문서화 적용
@NotBlank, @Email, @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")이 올바르게 추가되었습니다.

Comment on lines 35 to 37
log.info("authUserEmail: {}, authUserID : {}", authUser.getEmail(), authUser.getId());
return ResponseEntity.status(HttpStatus.OK).body(userService.getUserInfo(authUser));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Comment on lines +52 to 56
@Operation(summary = "토큰 재발급", description = "리프레시 토큰을 이용하여 새로운 액세스 토큰을 발급합니다.")
@PostMapping("/auth/refresh")
public ResponseEntity<RefreshTokenResponse> refresh(HttpServletRequest request) {
return ResponseEntity.status(HttpStatus.OK).body(authService.refreshToken(request));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

서비스 계층 분리: 토큰 재발급 요청 객체 제한 필요
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.

Suggested change
@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.

Comment on lines +44 to 49
@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));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

서비스 계층 분리: 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.

Suggested change
@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.

@minjee2758 minjee2758 changed the title Refactor/security Swagger 추가 및 리팩토링 Jun 12, 2025
@pokerbearkr
Copy link
Contributor

Docs :

@minjee2758 minjee2758 changed the title Swagger 추가 및 리팩토링 docs : Swagger 추가 및 리팩토링 Jun 12, 2025
@pokerbearkr pokerbearkr merged commit 4c8b11b into dev Jun 12, 2025
2 checks passed
@pokerbearkr pokerbearkr deleted the refactor/security branch June 12, 2025 07:07
@pokerbearkr pokerbearkr added the documentation Improvements or additions to documentation label Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants