-
Notifications
You must be signed in to change notification settings - Fork 0
Feat: [FN-60] 회원 탈퇴시 JWT 토큰 무효화 #8
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
|
Caution Review failedThe pull request is closed. """ Walkthrough토큰 버전 관리 및 검증 기능이 추가되었습니다. User 엔티티와 JWT 처리 로직에 tokenVersion 필드가 도입되어, 로그아웃·탈퇴 등에서 토큰 무효화가 가능해졌습니다. Redis를 활용한 토큰 버전 캐싱 및 관련 서비스, 저장소, 설정이 함께 도입되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthService
participant JwtComponent
participant TokenVersionService
participant TokenVersionRedisRepository
participant UserRepository
Client->>AuthService: login(로그인 요청)
AuthService->>JwtComponent: generateTokenPair(User)
JwtComponent->>User: User 정보에서 tokenVersion 추출
JwtComponent-->>AuthService: TokenPair 반환
Note over AuthService,JwtComponent: JWT에는 tokenVersion이 포함됨
Client->>JwtComponent: extractUserAuthFromToken(JWT)
JwtComponent->>TokenVersionService: findTokenVersion(userId)
TokenVersionService->>TokenVersionRedisRepository: getTokenVersion(userId)
alt Redis에 없음
TokenVersionRedisRepository-->>TokenVersionService: 없음
TokenVersionService->>UserRepository: findTokenVersionById(userId)
UserRepository-->>TokenVersionService: tokenVersion 반환
TokenVersionService->>TokenVersionRedisRepository: saveTokenVersion(userId, tokenVersion)
end
TokenVersionService-->>JwtComponent: tokenVersion 반환
JwtComponent->>JwtComponent: validateToken(UserAuth)
alt 토큰 버전 불일치
JwtComponent-->>Client: SecurityException 발생
else
JwtComponent-->>Client: UserAuth 반환
end
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✨ Finishing Touches
🪧 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: 2
🔭 Outside diff range comments (1)
src/main/java/project/flipnote/common/security/jwt/JwtComponent.java (1)
56-67: 토큰 생성 시 tokenVersion 클레임 누락
generateToken메서드에서tokenVersion을 JWT 클레임에 추가하지 않고 있습니다. 이로 인해 토큰 파싱 시extractUserAuthFromClaims메서드에서 NPE가 발생할 것입니다.다음과 같이 수정해야 합니다:
private String generateToken(User user, Date expiration) { Date now = new Date(); return Jwts.builder() .subject(user.getEmail()) .id(String.valueOf(user.getId())) .claim(JwtConstants.ROLE, user.getRole().name()) + .claim(JwtConstants.TOKEN_VERSION, user.getTokenVersion()) .issuedAt(now) .expiration(expiration) .signWith(secretKey, Jwts.SIG.HS256) .compact(); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
src/main/java/project/flipnote/auth/constants/AuthRedisKey.java(1 hunks)src/main/java/project/flipnote/auth/repository/TokenVersionRedisRepository.java(1 hunks)src/main/java/project/flipnote/auth/service/AuthService.java(1 hunks)src/main/java/project/flipnote/auth/service/TokenVersionService.java(1 hunks)src/main/java/project/flipnote/common/config/RedisConfig.java(2 hunks)src/main/java/project/flipnote/common/security/dto/UserAuth.java(1 hunks)src/main/java/project/flipnote/common/security/jwt/JwtComponent.java(3 hunks)src/main/java/project/flipnote/common/security/jwt/JwtConstants.java(1 hunks)src/main/java/project/flipnote/user/entity/User.java(2 hunks)src/main/java/project/flipnote/user/repository/UserRepository.java(2 hunks)src/main/java/project/flipnote/user/service/UserService.java(3 hunks)src/test/java/project/flipnote/auth/service/AuthServiceTest.java(4 hunks)
🔇 Additional comments (21)
src/main/java/project/flipnote/common/security/jwt/JwtConstants.java (1)
12-12: 상수 추가가 적절합니다.JWT 클레임 키로 사용할
TOKEN_VERSION상수가 올바르게 추가되었습니다. snake_case 네이밍 컨벤션을 따르고 있어 JWT 표준에 부합합니다.src/main/java/project/flipnote/common/security/dto/UserAuth.java (1)
15-15: 토큰 버전 필드 추가가 적절합니다.
UserAuth레코드에tokenVersion필드가 올바르게 추가되어 토큰 버전 관리 기능을 지원합니다.long타입 사용과 네이밍 컨벤션이 적절합니다.src/main/java/project/flipnote/auth/constants/AuthRedisKey.java (1)
11-13: Redis 키 상수 추가가 적절합니다.토큰 버전 관리를 위한
TOKEN_VERSION상수가 올바르게 추가되었습니다. 키 패턴"auth:token:version:%d"과 TTL 3600초가 적절합니다. trailing comma 사용도 좋은 관례입니다.src/main/java/project/flipnote/common/config/RedisConfig.java (1)
22-29: Redis 템플릿 설정이 적절합니다.토큰 버전 관리를 위한
RedisTemplate<String, Long>빈이 올바르게 구성되었습니다. 키 직렬화에StringRedisSerializer, 값 직렬화에GenericToStringSerializer<Long>사용이 적절하며 기존 패턴과 일관성을 유지합니다.src/test/java/project/flipnote/auth/service/AuthServiceTest.java (4)
181-181: JWT 생성 메서드 시그니처 변경에 맞게 테스트가 올바르게 업데이트되었습니다.
jwtComponent.generateTokenPair(foundUser)호출이 새로운 API에 맞게 수정되어User객체를 전달하도록 변경되었습니다.
191-191: 검증 로직이 새로운 메서드 시그니처에 맞게 적절히 수정되었습니다.
verify(jwtComponent).generateTokenPair(any(User.class))호출이 변경된 API를 올바르게 검증합니다.
211-211: 실패 케이스 테스트의 검증 로직이 올바르게 업데이트되었습니다.잘못된 이메일 케이스에서
generateTokenPair메서드가 호출되지 않음을 검증하는 로직이 새로운 시그니처에 맞게 수정되었습니다.
234-234: 비밀번호 불일치 케이스의 검증 로직이 적절히 수정되었습니다.잘못된 비밀번호 케이스에서도
generateTokenPair메서드 호출이 없음을 검증하는 로직이 올바르게 업데이트되었습니다.src/main/java/project/flipnote/user/service/UserService.java (2)
10-10: 토큰 버전 관리를 위한 Redis Repository 의존성 추가가 적절합니다.JWT 토큰 무효화 기능 구현을 위해 필요한 의존성이 올바르게 추가되었습니다.
Also applies to: 28-28
60-61: 사용자 탈퇴 시 토큰 무효화 로직이 올바르게 구현되었습니다.
user.unregister()호출로 토큰 버전을 증가시키고, Redis에서 토큰 버전을 삭제하는 순서가 적절합니다. 이를 통해 기존 JWT 토큰들이 무효화됩니다.src/main/java/project/flipnote/auth/service/AuthService.java (1)
44-44: JWT 토큰 생성 방식 개선이 적절합니다.토큰 버전 관리를 위해 User 객체 전체를 전달하는 방식으로 변경된 것이 합리적입니다. 이를 통해 tokenVersion을 포함한 모든 필요한 정보가 JWT 생성에 활용될 수 있습니다.
src/main/java/project/flipnote/user/repository/UserRepository.java (1)
22-23: 토큰 버전 조회를 위한 JPQL 쿼리가 적절합니다.성능 최적화를 위해 필요한 tokenVersion 필드만 조회하는 것이 효율적입니다.
src/main/java/project/flipnote/user/entity/User.java (4)
58-59: 토큰 버전 필드 추가가 적절합니다.JWT 토큰 무효화를 위한
tokenVersion필드가 올바르게 정의되었습니다.nullable = false설정도 적절합니다.
80-80: 토큰 버전 초기값 설정이 적절합니다.새로운 사용자의 토큰 버전을 0으로 초기화하는 것이 합리적입니다.
83-89: 사용자 탈퇴 시 토큰 무효화 로직이 올바르게 구현되었습니다.메서드명 변경(
softDelete→unregister)과 토큰 버전 증가 로직이 적절하게 추가되었습니다. 이를 통해 탈퇴한 사용자의 기존 JWT 토큰들이 무효화됩니다.
91-93: 토큰 버전 증가 메서드가 간결하고 명확합니다.토큰 버전을 1씩 증가시키는 로직이 명확하게 구현되었습니다.
src/main/java/project/flipnote/auth/service/TokenVersionService.java (1)
18-27: Redis 캐시와 DB 백업을 활용한 토큰 버전 조회 로직이 효율적으로 구현되었습니다.캐시 우선 전략을 통해 성능을 최적화하고, cache miss 시 DB에서 조회 후 캐시에 저장하는 로직이 적절합니다. Optional 체이닝을 통한 구현도 깔끔합니다.
src/main/java/project/flipnote/auth/repository/TokenVersionRedisRepository.java (2)
18-23: LGTM!토큰 버전을 TTL과 함께 Redis에 저장하는 로직이 올바르게 구현되었습니다.
32-36: LGTM!토큰 버전 삭제 로직이 올바르게 구현되었습니다.
src/main/java/project/flipnote/common/security/jwt/JwtComponent.java (2)
69-75: 토큰 검증 로직이 적절히 구현됨JWT 파싱 후 토큰 버전을 검증하는 로직이 올바르게 추가되었습니다.
91-98: LGTM!토큰 버전 검증 로직이 명확하고 올바르게 구현되었습니다. 사용자 탈퇴 시 토큰 무효화가 제대로 작동할 것으로 보입니다.
src/main/java/project/flipnote/user/repository/UserRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/project/flipnote/auth/repository/TokenVersionRedisRepository.java
Outdated
Show resolved
Hide resolved
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: 0
🧹 Nitpick comments (1)
src/test/java/project/flipnote/user/service/UserServiceTest.java (1)
163-163: 토큰 버전 삭제 검증 로직이 추가됨회원 탈퇴시 토큰 버전이 삭제되는지 검증하는 로직이 적절히 추가되었습니다. 현재
anyLong()매처를 사용하고 있는데, 더 엄격한 테스트를 위해 실제 사용자 ID로 검증하는 것을 고려해볼 수 있습니다.- verify(tokenVersionRedisRepository, times(1)).deleteTokenVersion(anyLong()); + verify(tokenVersionRedisRepository, times(1)).deleteTokenVersion(user.getId());
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/test/java/project/flipnote/user/service/UserServiceTest.java(3 hunks)
🔇 Additional comments (2)
src/test/java/project/flipnote/user/service/UserServiceTest.java (2)
20-20: 새로운 의존성 import가 적절히 추가됨토큰 버전 관리 기능을 위한 TokenVersionRedisRepository import가 올바르게 추가되었습니다.
47-48: Mock 의존성이 올바르게 구성됨TokenVersionRedisRepository에 대한 mock 필드가 적절한 어노테이션과 함께 추가되었습니다.
📝 변경 내용
✅ 체크리스트
💬 기타 참고 사항
Summary by CodeRabbit
신규 기능
개선 사항
버그 수정
테스트