Skip to content

🔀 Jwt Login#24

Merged
ohyuchan123 merged 8 commits intodevelopfrom
feature/jwt-login
Jan 6, 2025
Merged

🔀 Jwt Login#24
ohyuchan123 merged 8 commits intodevelopfrom
feature/jwt-login

Conversation

@ohyuchan123
Copy link
Member

@ohyuchan123 ohyuchan123 commented Jan 6, 2025

📌 관련 이슈

#22 Jwt 로그인 구현

✨ 과제 내용

기존 세션 기반 인증에서 JWT 기반 인증으로 전환했습니다. 보안 강화를 위해 토큰을
HttpOnly 쿠키에 저장하는 방식을 채택했으며, 다음과 같은 보안 조치를 적용했습니다:

📸 스크린샷(선택)

image

📚 레퍼런스 (또는 새로 알게 된 내용) 혹은 궁금한 사항들

Summary by CodeRabbit

릴리즈 노트

  • 새로운 기능

    • JWT 기반 인증 시스템 도입
    • 로그인, 로그아웃, 회원가입 엔드포인트 추가
    • 보안 강화를 위한 토큰 인증 메커니즘 구현
  • 개선 사항

    • 사용자 인증 프로세스 최적화
    • API 보안 수준 향상
    • 쿠키 기반 토큰 관리 시스템 구축
  • 기술적 변경

    • Spring Security 설정 업데이트
    • JWT 라이브러리 의존성 추가
    • 인증 관련 컴포넌트 재구성

@ohyuchan123 ohyuchan123 self-assigned this Jan 6, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2025

Walkthrough

이 풀 리퀘스트는 애플리케이션의 인증 및 보안 메커니즘을 전면적으로 재설계합니다. JWT(JSON Web Token) 기반 인증 시스템을 도입하여 사용자 로그인, 로그아웃, 등록 프로세스를 개선합니다. 새로운 보안 구성, 인증 필터, 토큰 유틸리티 클래스를 추가하고 기존 등록 관련 컴포넌트를 리팩토링하여 더욱 안전하고 효율적인 인증 메커니즘을 구현합니다.

Changes

파일 변경 요약
build.gradle JWT 관련 의존성 3개 추가
SecurityConfig.java JWT 필터 및 인증 설정 업데이트
AuthController.java 새로운 인증 컨트롤러 생성
LoginRequestDto.java 로그인 요청 DTO 추가
LoginResponseDto.java 로그인 응답 DTO 추가
JWTFilter.java JWT 인증 필터 구현
JWTUtil.java JWT 토큰 생성 및 검증 유틸리티 클래스 추가

Sequence Diagram

sequenceDiagram
    participant Client
    participant AuthController
    participant AuthService
    participant JWTUtil
    participant MemberRepository

    Client->>AuthController: 로그인 요청
    AuthController->>AuthService: login(credentials)
    AuthService->>MemberRepository: findByEmail()
    MemberRepository-->>AuthService: Member
    AuthService->>JWTUtil: createToken(email)
    JWTUtil-->>AuthService: JWT 토큰
    AuthService-->>AuthController: 로그인 응답
    AuthController-->>Client: JWT 쿠키 및 사용자 정보
Loading

Possibly related PRs

Suggested labels

✅ Test, 🔨 Refactor, ✨ Feature

Poem

🐰 토큰의 토끼, 보안을 달리다
JWT의 길을 열어젖히니
쿠키는 반짝이고, 인증은 춤추네
보안의 문을 활짝 열어젖히는
우리의 작은 코드 마법! 🔐✨


🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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.

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

🧹 Nitpick comments (20)
src/main/java/com/mycom/socket/auth/config/SecurityConfig.java (2)

28-28: [CORS 설정 유연성 제안]

applyPermitDefaultValues()는 편리하지만, 프로덕션 환경에서는 도메인 및 메서드 제약을 좀 더 세밀하게 구성하는 것이 안전합니다. 필요에 따라 CORS 설정을 구체화하는 방안을 고려해 보세요.


40-40: [엔드포인트 접근 권한 검토]

"/","/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**" 경로에 대한 permitAll()은 편의성 면에서는 유익하지만, 민감한 API 문서는 운영 환경에서 접근을 제한해야 할 수도 있습니다. 필요 시 보안 정책을 재검토해 보세요.

src/main/java/com/mycom/socket/auth/jwt/JWTFilter.java (1)

24-49: [JWT 토큰 검증 로직]

doFilterInternal 메서드에서 쿠키에 담긴 토큰을 파싱하고, 토큰 유효성 검증 후 SecurityContextHolder에 인증 정보를 저장하는 흐름이 이상적입니다.

  • 토큰이 유효하지 않은 경우의 예외 처리가 간단하게 clearContext()로 처리되는데, 필요하다면 디버깅 용도 로깅을 추가해서 보안 이벤트 모니터링을 강화할 수 있습니다.
src/main/java/com/mycom/socket/auth/service/MemberDetailsService.java (1)

19-21: [KO] 예외 메시지를 구체적으로 작성해주세요.
"사용자를 찾을 수 없습니다." 라는 메시지 대신, 사용자의 이메일 정보 등을 포함하면 디버깅과 로깅에 좀 더 유용합니다.

-orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다."))
+orElseThrow(() -> new UsernameNotFoundException("해당 이메일(" + email + ")에 해당하는 사용자를 찾을 수 없습니다."))
src/main/java/com/mycom/socket/auth/controller/AuthController.java (1)

28-31: [KO] 로그아웃 로직 보강 제안
현재 로그아웃 시 쿠키의 JWT 토큰만 만료시키는지 여부가 궁금합니다. 세션 관리를 병행하거나 Redis 같은 인메모리 서비스를 활용하는 방식도 고려해 볼 수 있습니다.

src/main/java/com/mycom/socket/auth/security/MemberDetails.java (1)

37-55: [KO] 계정 상태 플래그 확인 필요
현재 isAccountNonExpired(), isAccountNonLocked(), isCredentialsNonExpired(), isEnabled()가 전부 true를 반환하고 있습니다. 이 값들을 멤버 필드로 관리할 계획이 있다면, 추후 확장에 대비해 getter 메소드를 별도로 지원하는 방안을 고민해 볼 수 있습니다.

src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (1)

22-35: [KO] 토큰 만료시간 상수화 권장
30분이라는 만료 시간 값을 코드 내에 직접 넣기보다는 상수나 설정 파일로 분리하여 유지보수에 유리하게 만드는 것을 권장합니다.

- long accessTokenValidityInMilliseconds = 1000 * 60 * 30;
+ private static final long ACCESS_TOKEN_VALIDITY_MS = 1000 * 60 * 30;
...
long accessTokenValidityInMilliseconds = ACCESS_TOKEN_VALIDITY_MS;
src/test/java/com/mycom/socket/member/service/RegisterServiceTest.java (2)

25-25: [KO] 테스트 클래스 명과 실제 대상 기능의 일치
RegisterServiceTest 라는 클래스명과 달리, 실제 테스트는 AuthService를 주입받아 등록 기능을 테스트하고 있습니다. 추후 혼동 방지를 위해 AuthServiceRegisterTest 등 더 직관적인 클래스명으로 변경을 고려해볼 수 있습니다.


Line range hint 36-60: [KO] 테스트에서 중복 검사 로직 추가 확인
이 메서드에서 이메일과 닉네임에 대한 중복 검사를 테스트하고 있지만, 중복 발생 시 예외를 던지는지, 어느 레벨에서 예외가 처리되는지 명확한 검증이 필요해 보입니다. 예외 상황 테스트(existsByEmail 혹은 existsByNickname이 true일 경우)에 대한 단위 테스트도 함께 제공하면 좋습니다.

src/test/java/com/mycom/socket/member/service/LoginIntegrationTest.java (2)

36-44: 테스트 멤버 초기화 로직 점검 필요
테스트 시작 전 멤버를 매번 새로 저장하므로, 동일 이메일로 인한 예외 상황 테스트를 고려할 수도 있습니다. 필요하다면 @BeforeEach에서 이미 존재하는 이메일 상황을 테스트 케이스로 분리해볼 수 있습니다.


54-65: 쿠키 설정에 대한 보안 점검
테스트에서 Authorization 쿠키가 HTTP-Only이자 Secure 플래그가 설정되어 30분 유효기간으로 검증되는 점은 좋습니다. 다만, 도메인 설정이 필요하다면 강화하여 보안성을 높일 수 있으니, 도메인도 명시 설정하는 방안을 고려해 볼 수 있습니다.

src/test/java/com/mycom/socket/member/controller/RegisterControllerTest.java (2)

34-34: AuthService에 대한 MockBean 구성 확인
AuthService를 컨트롤러 테스트용으로 MockBean 처리하는 것은 적절합니다. 다만, 회원가입 외에 로그인 기능 등 다른 메서드를 호출하지는 않는지 확인하고, 필요 시 별도의 테스트를 위해 Mock 동작을 분리해두는 것도 도움이 될 수 있습니다.


40-46: 회원가입 성공 테스트 케이스 로깅
회원가입 성공 시, 반환되는 id가 올바른지 여부만 확인하고 있습니다. 추가로 이메일 중복 체크, 닉네임 중복 체크 등의 내부 로직이 정상 호출되었는지 Mockito를 통해 좀 더 세부 검증해볼 수도 있습니다.

src/main/java/com/mycom/socket/auth/service/AuthService.java (3)

28-34: 로그인 로직 예외 처리 보완
BadRequestException 사용으로 이메일 미등록, 비밀번호 불일치 상황을 처리하고 있습니다. 보안상, 동일 메시지를 반환하거나 특정 상황별 커스텀 예외를 분리하는 방법도 있습니다. 만약 보안을 강화하고 싶다면, "잘못된 이메일 혹은 비밀번호"로 통합하여 공격자가 정보를 추론하기 어렵게 할 수 있습니다.


36-46: JWT 토큰 생성 시점에 대한 주의
로그인 시 바로 쿠키를 설정해주고 있습니다. 토큰 갱신(refresh) 또는 세션 만료 로직이 필요한 경우 이 부분이 연계되어야 하므로, 추후 확장에 대비해 로직을 분리(예: createCookieWithToken 메서드 등)하면 유지보수에 용이합니다.


57-66: 회원가입 중복 검사 로직 세분화
이메일, 닉네임 중복을 개별적으로 검사하고 있는데, 예외처리를 분리한 부분은 명확합니다. 비동기 환경에서 두 조건을 동시에 만족하지 않는 경쟁 조건이 발생할 수 있으므로, DB 레벨에서 Unique Index를 통해 최종적으로 보호하는지 함께 확인바랍니다.

src/main/java/com/mycom/socket/auth/security/LoginFilter.java (2)

31-45: 로그인 요청 처리 에러 메시지 세분화
RuntimeException으로 묶어서 던지는 대신, 명확한 커스텀 예외나 다른 예외 구분 방식을 도입할 수 있습니다. JSON 파싱 문제 등 상세 원인 파악이 필요할 때, 로그에서 추적이 쉽게 되도록 예외 타입을 세분화하세요.


74-83: 로그인 실패 처리
로그인 실패 시 401을 반환하고 있으며, "로그인에 실패했습니다. 이메일 또는 비밀번호를 확인해주세요."라는 메시지가 출력됩니다. 인증 실패 로깅이나 보안 모니터링 체계를 구축하려면, 추가적인 로그 기록(원격 IP, 시도 횟수) 등이 필요할 수 있습니다.

src/test/java/com/mycom/socket/member/service/LoginTest.java (2)

90-103: 이메일 미존재 예외 흐름 검증
이메일이 존재하지 않을 때 BadRequestException을 던져 정확히 검증하는 점은 좋습니다. 그러나 UI UX 측면에서 이메일 혹은 비밀번호가 틀렸을 때 동일한 메시지를 반환할지 분리할지 팀 정책을 재검토해볼 수도 있습니다.


105-128: 비밀번호 불일치 예외 처리 점검
비밀번호가 틀릴 경우 예외 발생 후 쿠키가 생성되지 않는 시나리오 확인이 적절합니다. 다만, 소셜 로그인 등 별도 인증체계가 도입될 경우에도 동일 로직을 재활용할 수 있는지 확인하여, AuthService의 구조를 확장성 있게 유지하시길 권장합니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 793fecb and 4ce724a.

📒 Files selected for processing (19)
  • build.gradle (1 hunks)
  • src/main/java/com/mycom/socket/auth/config/SecurityConfig.java (2 hunks)
  • src/main/java/com/mycom/socket/auth/controller/AuthController.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/dto/request/LoginRequestDto.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/dto/request/RegisterRequestDto.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/dto/response/LoginResponseDto.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/jwt/JWTFilter.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/security/LoginFilter.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/security/MemberDetails.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/service/AuthService.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/service/MemberDetailsService.java (1 hunks)
  • src/main/java/com/mycom/socket/go_socket/controller/RegisterController.java (0 hunks)
  • src/main/java/com/mycom/socket/go_socket/repository/MemberRepository.java (1 hunks)
  • src/main/java/com/mycom/socket/go_socket/service/RegisterService.java (0 hunks)
  • src/test/java/com/mycom/socket/member/controller/RegisterControllerTest.java (4 hunks)
  • src/test/java/com/mycom/socket/member/service/LoginIntegrationTest.java (1 hunks)
  • src/test/java/com/mycom/socket/member/service/LoginTest.java (1 hunks)
  • src/test/java/com/mycom/socket/member/service/RegisterServiceTest.java (4 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/com/mycom/socket/go_socket/service/RegisterService.java
  • src/main/java/com/mycom/socket/go_socket/controller/RegisterController.java
✅ Files skipped from review due to trivial changes (1)
  • src/main/java/com/mycom/socket/auth/dto/request/RegisterRequestDto.java
🔇 Additional comments (19)
src/main/java/com/mycom/socket/auth/config/SecurityConfig.java (3)

3-5: [임포트 추가 사항]

JWT 관련 클래스(JWTFilter, JWTUtil, MemberDetailsService)를 임포트하는 구문입니다. JWT 기반 인증 흐름에 필요한 컴포넌트들이 적절히 구성된 것으로 보입니다. 스프링 시큐리티 필터(UsernamePasswordAuthenticationFilter)를 확장/보완하기 위한 임포트도 문제 없어 보입니다.

Also applies to: 14-14


22-23: [주입 필드 확인]

private final 필드 선언을 통해 생성자 주입(@requiredargsconstructor)을 사용하는 구성입니다. jwtUtilmemberDetailsService가 정상적으로 DI 되어 사용되도록, 환경 구성이나 빈 등록에 누락된 부분이 없는지 최종 확인해주세요.


33-33: [JWT 필터 체인 설정]

UsernamePasswordAuthenticationFilter 이전에 JWTFilter를 두어 쿠키 기반 JWT 검증을 실행하는 것은 적절한 접근입니다. 다만, JWTFilter에서 예외 발생 시 충분한 로깅 및 에러 처리가 이루어지는지 함께 점검해 주세요.

src/main/java/com/mycom/socket/auth/jwt/JWTFilter.java (3)

18-19: [클래스 선언 및 롬복 설정]

@RequiredArgsConstructor를 통해 필요한 의존성을 생성자 주입 받는 구조는 간결하고 유지보수에 용이합니다.


21-23: [JWT 관련 필드]

jwtUtilmemberDetailsService 필드가 JWT 토큰 검증과 사용자 정보 로딩에 사용됩니다. 명확한 책임 분리로 필터 내에서 인증 절차를 직관적으로 처리할 수 있어 보입니다.


51-61: [쿠키에서 토큰 추출 로직]

"Authorization" 이름의 쿠키를 탐색하여 토큰을 추출하는 부분은 간단하고 명확합니다. 보안 강화를 위해 쿠키 설정(예: HttpOnly, Secure 옵션)이 함께 적용되어 있는지 확인해 보세요.

src/main/java/com/mycom/socket/auth/dto/response/LoginResponseDto.java (1)

1-10: [로그인 응답 DTO]

record 구문으로 최소한의 코드로 DTO를 구성한 점이 간결하고 좋습니다. of 정적 팩토리 메서드를 활용해 명확하게 객체를 생성할 수 있어 유지보수 측면에도 유리합니다.

src/main/java/com/mycom/socket/auth/dto/request/LoginRequestDto.java (1)

3-13: [로그인 요청 검증]

@NotBlank@Email을 통해 이메일 형식과 공백 검증을 수행하는 점이 적절합니다. 잘못된 형식이 들어올 때 자동으로 예외가 발생하므로, API 사용성 및 보안 면에서 유리합니다.

src/main/java/com/mycom/socket/go_socket/repository/MemberRepository.java (1)

6-7: [이메일 기반 조회 메서드 추가]

Optional<Member> findByEmail(String email) 메서드를 추가하여 회원 검색 기능이 확장되었습니다. 이를 통해 이메일을 통한 인증 및 사용자 정보 조회가 더욱 명확해질 것으로 보입니다.

Also applies to: 11-11

src/main/java/com/mycom/socket/auth/service/MemberDetailsService.java (1)

16-16: [KO] 서비스 주입 방식을 확인해주세요.
memberRepository@RequiredArgsConstructor로 주입되고 있으므로, 다른 의존성도 모두 동일한 Lombok 방식으로 주입하는 것이 일관성 유지에 좋습니다.

src/main/java/com/mycom/socket/auth/controller/AuthController.java (2)

20-25: [KO] 로그인 API 반환 타입과 구현을 확인해주세요.
authService.login(request, response)가 LoginResponseDto를 반환하고 있는데, 예외 상황 혹은 유효성 검증 실패 시 어떤 처리를 하는지 검토가 필요합니다. Spring에서 발생할 수 있는 MethodArgumentNotValidException을 처리할 글로벌 예외 처리가 함께 구현되어 있는지도 확인해주세요.


33-36: [KO] 회원가입 시 예외 처리 로직 확인 필요
회원가입 중복 검사에서 발생하는 예외나, 비밀번호 정책 위반의 경우 등을 어떻게 처리하고 있는지 확인이 필요합니다. AuthService 단에서 처리하지 않은 예외가 있을 경우, 컨트롤러 단에서 명시적으로 처리하도록 검토해주세요.

src/main/java/com/mycom/socket/auth/security/MemberDetails.java (1)

23-23: [KO] ROLE 설정 검토
member.getRole()을 직접 사용하고 있지만, DB나 Enum 정의 구조상 "ROLE_" 접두사를 붙여야 할 수도 있습니다. Spring Security 표준 관례에 맞게 ROLE_USER, ROLE_ADMIN 등 문자열로 설정하는지 확인해주세요.

src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (1)

49-56: [KO] 토큰 파싱 시 예외 처리
getEmail에서 parseSignedClaims를 실행할 때 토큰 검증에 실패하면 예외가 발생할 수 있으므로, 추가적인 예외 처리가 필요해 보입니다.

src/test/java/com/mycom/socket/member/service/LoginIntegrationTest.java (1)

49-50: 요청 DTO 테스트에 대한 추가 검증 제안
LoginRequestDto가 값이 비어 있거나 잘못된 형식임을 확인하는 테스트가 없습니다. 로그인 실패 시나리오를 추가 작성해, DTO 검증 로직이 제대로 수행되는지 확인하면 좋겠습니다.

src/test/java/com/mycom/socket/member/controller/RegisterControllerTest.java (1)

63-63: 유효성 검증 테스트 확장 제안
현재는 잘못된 이메일, 너무 짧은 닉네임, 짧은 비밀번호 정도만 테스트하고 있습니다. 실제 DTO 검증 로직이 더 복잡하다면, 경계값 테스트(예: 최대 길이, 특수문자 포함 여부 등)를 추가해서 보다 탄탄한 회원가입 검증 시나리오를 구성해보면 좋겠습니다.

src/main/java/com/mycom/socket/auth/service/AuthService.java (1)

82-89: 로그아웃 쿠키 제거 로직 보완
logout 메서드는 쿠키를 즉시 만료시키고 있지만, 로컬 개발 환경이 아닌 실제 배포 환경에서는 도메인 설정이 필요할 수도 있습니다. 도메인 미설정 시 쿠키가 제거되지 않는 문제가 있을 수 있으므로, 실제 운영 환경 뒤에서 도메인을 설정하는지 재확인해 보세요.

src/test/java/com/mycom/socket/member/service/LoginTest.java (1)

44-66: 로그인 성공 시 쿠키 유효성 테스트
쿠키의 maxAge, HttpOnly, Secure 플래그가 모두 설정되는 것을 점검하고 있습니다. 만약 도메인 설정이 필요한 프로젝트 환경이라면, 쿠키의 도메인도 검증 로직에 포함할 수 있습니다.

build.gradle (1)

62-64: JWT 라이브러리 추가 확인 필요

이 의존성들은 JWT 기능 구현에 핵심적인 역할을 합니다. 버전 호환성과 최신 보안 공지 사항을 재확인하시길 권장드립니다.

다음 스크립트를 실행하여 최신 버전 및 보안 이슈를 점검해보세요:

Comment on lines 37 to 47
public boolean validateToken(String token) {
try {
Jwts.parser()
.verifyWith(secretKey)
.build()
.parseSignedClaims(token);
return true;
} catch (Exception e) {
return false;
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

[KO] 예외 처리 로깅 보강
validateToken 메서드에서 Exception 발생 시 단순히 return false로 처리하고 있습니다. 불필요한 토큰 접근이 반복될 경우를 대비해 최소한의 에러 로그를 남기는 것이 좋습니다.

} catch (Exception e) {
+   log.warn("JWT 토큰 검증 중 예외 발생: {}", e.getMessage());
    return false;
}

Committable suggestion skipped: line range outside the PR's diff.

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(RegisterController.class)
@WebMvcTest(AuthController.class)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

@WebMvcTest 사용 시 Controller 범위 확인
@WebMvcTest(AuthController.class)로 지정되어 있지만, 클래스명은 RegisterControllerTest로 남아 있습니다. 테스트 대상 클래스 이름과 실제 테스트하는 컨트롤러가 일치하도록 수정하거나, 파일명을 AuthControllerTest 등으로 변경하여 혼동을 줄이는 편이 좋겠습니다.

Comment on lines 50 to 62
MemberDetails memberDetails = (MemberDetails) authResult.getPrincipal();
Member member = memberDetails.getMember();

// JWT 토큰 생성
String token = jwtUtil.createToken(member.getEmail());

// HTTP Only 쿠키에 JWT 토큰 저장
Cookie cookie = new Cookie("Authorization", token);
cookie.setHttpOnly(true); // JavaScript에서 접근 불가능하게 설정
cookie.setSecure(true); // HTTPS에서만 전송되도록 설정
cookie.setPath("/"); // 모든 경로에서 쿠키 접근 가능
cookie.setMaxAge(1800); // 쿠키 만료시간 30분
response.addCookie(cookie);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

JWT 토큰 쿠키 설정 시 취약점 확인
Authorization 쿠키에 JWT가 설정되어 있는데, 프론트엔드에서 CSRF 공격에 대해 대비하는지 확인해야 합니다. HTTP-Only, Secure 설정은 잘 되어 있으나, 보안 요구사항에 따라 SameSite 설정(SameSite=Strict 또는 Lax)을 고려하는 것이 좋습니다.

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 (7)
src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (3)

18-22: [KO] 비밀 키 보안 강화 제안
현재 코드는 애플리케이션 시작 시점에 환경 변수(@Value("${jwt.secret}"))로부터 비밀 키를 받아 SecretKey를 생성하고 있습니다. 이 때, 비밀 키 관리가 어플리케이션 내 환경 변수 설정에만 의존할 경우, 배포 환경에서 누출 위험이 있을 수 있습니다. Secret Manager(예: AWS Secrets Manager, HashiCorp Vault 등)나 컨테이너 오케스트레이션 툴에서 제공하는 비밀 키 관리 기능을 적극 고려해 보안성을 한층 높일 수 있습니다.


24-37: [KO] 토큰 생성 시 추가적인 클레임 고려
토큰에 담길 정보를 email만 사용하는 경우, 차후 사용자 관련된 다양한 정보를 추가하기 어려울 수 있습니다. 역할(Role)이나 권한(Permission)과 같은 추가 클레임을 함께 저장하면, 인가 단계에서 토큰만으로 특정 리소스 접근 권한을 빠르게 검증할 수 있어 확장성이 높아집니다.


52-59: [KO] 파서 구성 주의
토큰에서 이메일을 추출하기 위해 parseSignedClaims(token).getPayload().getSubject()를 사용하고 있습니다. 현재 로직에는 문제가 없지만, 확장 또는 다른 클레임 파싱 시점을 고려할 때, 파싱 과정을 유연하게 재사용할 수 있도록 별도의 헬퍼 메서드(예: parseClaims(token))를 두면 가독성과 유지보수성이 향상될 수 있습니다.

src/test/java/com/mycom/socket/member/controller/AuthControllerTest.java (4)

23-25: 테스트 대상 컨트롤러 변경에 따른 영향
@WebMvcTest(AuthController.class)로 설정이 변경되면서 AuthController를 테스트 대상으로 삼고 있습니다. SecurityConfig를 임포트하여 시큐리티 컨텍스트를 올바르게 구성하고 있습니다. 기타 보안 설정(예: JwtFilter 등)을 통합 테스트로도 점검해 보는 것을 권장드립니다.


34-34: MockBean 주입 대체 검토
@MockBean으로 AuthService를 주입받아 테스트하고 있습니다. 주요 로직이 복잡해질 경우, 실제 Bean을 사용하거나 분리된 통합 테스트를 고려해볼 수 있습니다.


46-46: Service 계층 스텁 확인
authService.register(any(RegisterRequestDto.class))의 스텁을 1L로 반환하도록 설정한 부분은 정상 동작을 확인하기에 충분합니다. 단, 추가적인 예외 케이스나 검증 로직에 대한 시나리오도 함께 테스트한다면 품질 향상에 도움이 될 것입니다.


63-63: 예외 케이스 테스트 보완 제안
이메일 형식 검증, 이름 길이 제한, 비밀번호 검증 등을 제대로 처리하는지 테스트에 포함되어 있습니다. 다만, 세부 검증 로직(예: 공백 문자, 특수 문자 등)을 좀 더 다양하게 포함하면 전반적인 입력 유효성 검증이 한층 강화될 것입니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ce724a and 8f39fd6.

📒 Files selected for processing (3)
  • src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (1 hunks)
  • src/main/java/com/mycom/socket/auth/security/LoginFilter.java (1 hunks)
  • src/test/java/com/mycom/socket/member/controller/AuthControllerTest.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/mycom/socket/auth/security/LoginFilter.java
🔇 Additional comments (3)
src/main/java/com/mycom/socket/auth/jwt/JWTUtil.java (1)

39-49: [KO] 예외 처리 로깅 보강
현재 validateToken 메서드의 예외 처리 부분에서는 `` 태그가 필요한 과거 코멘트와 거의 동일한 로깅 방식을 사용하고 있습니다. 예외가 발생했을 때 최소한의 로그를 남긴 것은 인상적입니다. 다만, 반복적이고 악의적인 토큰 시도가 있을 경우를 대비하여, 예외 발생 타이밍과 횟수를 구분하여 경고 로그 레벨 이상의 조치를 취하는 방법도 검토해 볼 수 있습니다.

src/test/java/com/mycom/socket/member/controller/AuthControllerTest.java (2)

5-7: 주요 의존성 수정 확인
AuthController, RegisterRequestDto, AuthService를 새로 임포트하여 기존의 RegisterController 관련 의존성을 대체하고 있습니다. 전반적인 구조를 잘 반영하였으나, 기존 컨트롤러와 DTO의 로직 차이가 없는지 한 번 더 확인해보시면 좋겠습니다.


40-40: 테스트 데이터 검증
회원가입 요청 DTO를 생성할 때 "안녕하세요"와 같은 문자 입력도 포함하여 유니코드 처리가 정상적으로 이뤄지는지 확인할 수 있습니다. 다양한 언어와 특수 문자를 테스트 데이터에 포함하여 포괄적인 검증을 권장합니다.

@ohyuchan123 ohyuchan123 added ✅ Test test 관련(storybook, jest...) 🔨 Refactor 코드 리팩토링 ✨ Feature 기능 개발 labels Jan 6, 2025
@ohyuchan123 ohyuchan123 merged commit 32785e8 into develop Jan 6, 2025
1 of 2 checks passed
@ohyuchan123 ohyuchan123 changed the title Jwt Login 🔀 Jwt Login Jan 6, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 8, 2025
@ohyuchan123 ohyuchan123 deleted the feature/jwt-login branch January 8, 2025 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발 🔨 Refactor 코드 리팩토링 ✅ Test test 관련(storybook, jest...)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant