-
Notifications
You must be signed in to change notification settings - Fork 2
관리자 계정에 다중 refreshToken을 지원한다 #973
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
관리자 계정에 다중 refreshToken을 지원한다 #973
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | 변경 요약 |
|---|---|
User 엔티티backend/src/main/java/moadong/user/entity/User.java |
refreshToken: RefreshToken → refreshTokens: List<RefreshToken>로 변경(@Field("refreshTokens"), @Builder.Default로 빈 ArrayList 초기화). 컬렉션 관리 메서드 추가: addRefreshToken, replaceRefreshToken, removeRefreshToken, removeAllRefreshTokens. 기존 updateRefreshToken 제거. List/ArrayList 임포트 추가. |
저장소 쿼리backend/src/main/java/moadong/user/repository/UserRepository.java |
쿼리 메서드명 변경: findUserByRefreshToken_Token(...) → findUserByRefreshTokens_Token(...) (토큰 검색 대상 컬렉션명 반영). |
서비스 로직backend/src/main/java/moadong/user/service/UserCommandService.java |
로그인: 새 토큰을 컬렉션에 추가; 로그아웃: 컬렉션에서 특정 토큰 제거(토큰으로 사용자 조회 변경); 리프레시: 토큰 존재 여부 확인 후 만료 검사 및 replaceRefreshToken 호출; 사용자 업데이트/임시비밀번호(리셋): 모든 리프레시 토큰 제거 및 새 토큰 추가. 쿠키 생성/갱신 로직이 새 토큰 값에 맞게 조정됨. |
Sequence Diagram(s)
sequenceDiagram
participant Client as 클라이언트
participant Service as UserCommandService
participant Repo as UserRepository
participant DB as MongoDB
Note over Service,Repo: 로그인 / 토큰 갱신 흐름 (다중 refreshTokens)
Client->>Service: 로그인 요청 (credentials)
Service->>Repo: findByEmail(...)
Repo->>DB: 사용자 조회
DB-->>Repo: 사용자 도큐먼트 (refreshTokens: [])
Repo-->>Service: User
Service->>Service: generateRefreshToken()
Service->>User: addRefreshToken(newRefreshToken)
Service->>Repo: save(User)
Repo->>DB: 사용자 업데이트 (refreshTokens에 새 토큰 추가)
DB-->>Repo: 저장 완료
Repo-->>Service: 저장된 User
Service-->>Client: 응답 + Set-Cookie (newRefreshToken.token)
Estimated code review effort
🎯 3 (보통) | ⏱️ ~20분
Possibly related issues
- MOA-405: 관리자계정에 다중 refreshToken을 지원한다 — 본 PR은 사용자 엔티티에 다중 refreshToken 컬렉션을 도입하는 작업으로 해당 목표와 일치함.
- [feature] MOA-405 관리자계정에 다중 refreshToken을 지원한다 #911: 단일 refreshToken → 다중 refreshTokens 변경 관련 이슈 — 메서드/쿼리/서비스 로직 업데이트가 이 이슈의 요구사항과 직접적으로 부합함.
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title accurately describes the main change: implementing support for multiple refresh tokens in admin accounts to enable simultaneous login from multiple devices. |
| Linked Issues check | ✅ Passed | The pull request successfully implements the core objective from MOA-405: changing from single to multiple refresh token support with new collection management methods, repository query updates, and service layer modifications. |
| Out of Scope Changes check | ✅ Passed | All changes are directly aligned with the stated objective of adding multiple refresh token support; no unrelated modifications were introduced. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
feature/#911-admin-multi-refresh-token-MOA-405
📜 Recent review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
backend/src/main/java/moadong/user/service/UserCommandService.java
🔇 Additional comments (6)
backend/src/main/java/moadong/user/service/UserCommandService.java (6)
79-79: 다중 토큰 지원을 위한 올바른 구현입니다.단일 토큰 업데이트에서 컬렉션에 토큰을 추가하는 방식으로 변경되어 여러 기기에서 동시 로그인이 가능합니다.
88-92: 로그아웃 로직이 다중 토큰 구조에 맞게 올바르게 변경되었습니다.특정 토큰만 제거하여 다른 기기의 로그인 세션은 유지됩니다.
123-123: 토큰 갱신 로직이 올바르게 구현되었습니다.특정 토큰만 새 토큰으로 교체하여 다른 기기의 세션에 영향을 주지 않습니다.
148-150: 비밀번호 변경 시 모든 토큰을 제거하는 보안 처리가 적절합니다.모든 기기에서 재로그인을 요구하여 계정 보안을 강화합니다.
154-154: 쿠키 생성이 새로운 RefreshToken 구조에 맞게 올바르게 업데이트되었습니다.
169-169: 임시 비밀번호 발급 시 모든 토큰을 제거하는 보안 처리가 적절합니다.비밀번호 재설정 후 모든 기존 세션을 무효화하여 보안을 강화합니다.
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
Test Results75 tests 72 ✅ 19s ⏱️ Results for commit 32ee4ac. ♻️ This comment has been updated with latest results. |
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: 1
🧹 Nitpick comments (3)
backend/src/main/java/moadong/user/service/UserCommandService.java (1)
79-80: 토큰 개수 제한 및 정리 전략을 고려하세요.현재 구현에서는 사용자당 리프레시 토큰 개수에 제한이 없습니다. 다음 사항들을 검토하시기 바랍니다:
토큰 개수 제한: 사용자가 로그아웃 없이 계속 로그인하면 토큰이 무제한으로 누적될 수 있습니다. 최대 토큰 개수를 설정하고 오래된 토큰을 자동으로 제거하는 정책을 고려하세요 (예: 최대 5개 기기).
만료된 토큰 정리: 만료된 토큰이 DB에 계속 남아있습니다. 주기적인 정리 작업(scheduled job)이나 로그인 시 만료 토큰 제거 로직을 추가하는 것이 좋습니다.
기기 식별: 현재는 어떤 토큰이 어떤 기기에서 사용되는지 추적할 수 없습니다. 향후 "다른 기기에서 로그아웃" 같은 기능을 위해 기기 정보(User-Agent, 기기명 등)를 RefreshToken에 포함하는 것을 고려하세요.
backend/src/main/java/moadong/user/entity/User.java (2)
107-118: 토큰을 찾지 못한 경우의 처리를 개선하세요.
replaceRefreshToken메서드가oldToken을 찾지 못하면 아무 작업 없이 조용히 반환됩니다. 이는 토큰 교체가 예상되지만 실제로 발생하지 않는 버그를 숨길 수 있습니다.다음 중 하나를 고려하세요:
- 토큰을 찾지 못한 경우 예외를 던지기
- 경고 로그 남기기
- 반환 타입을 boolean으로 변경하여 성공 여부를 알리기
🔎 예외 처리 추가 제안
public void replaceRefreshToken(String oldToken, RefreshToken newToken) { if (this.refreshTokens == null) { this.refreshTokens = new ArrayList<>(); - return; + throw new IllegalStateException("토큰 교체 실패: 리프레시 토큰 목록이 비어있습니다."); } for (int i = 0; i < this.refreshTokens.size(); i++) { if (this.refreshTokens.get(i).getToken().equals(oldToken)) { this.refreshTokens.set(i, newToken); return; } } + throw new IllegalArgumentException("토큰 교체 실패: 기존 토큰을 찾을 수 없습니다."); }
127-133: 전체 토큰 제거 메서드의 null 처리를 단순화할 수 있습니다.현재 구현은
refreshTokens가 null일 때 새 ArrayList를 초기화한 후 바로 반환합니다(129-130행). null인 경우 초기화 없이 바로 반환하거나, null이 아닐 때만 clear를 호출하는 것이 더 명확합니다.🔎 단순화 제안
public void removeAllRefreshTokens() { - if (this.refreshTokens == null) { - this.refreshTokens = new ArrayList<>(); - return; - } - this.refreshTokens.clear(); + if (this.refreshTokens != null) { + this.refreshTokens.clear(); + } }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
backend/src/main/java/moadong/user/entity/User.javabackend/src/main/java/moadong/user/repository/UserRepository.javabackend/src/main/java/moadong/user/service/UserCommandService.java
🔇 Additional comments (9)
backend/src/main/java/moadong/user/repository/UserRepository.java (1)
12-12: 메서드 이름 변경이 적절합니다.
refreshTokens컬렉션 필드와 일치하도록 메서드 이름이 올바르게 변경되었습니다. Spring Data MongoDB가 중첩 필드 쿼리를 정상적으로 처리할 것입니다.backend/src/main/java/moadong/user/service/UserCommandService.java (5)
79-80: 로그인 시 토큰 추가 로직이 올바릅니다.리프레시 토큰을 컬렉션에 추가하는 방식으로 다중 기기 로그인을 지원하도록 변경되었습니다.
88-92: 로그아웃 로직이 적절합니다.특정 리프레시 토큰만 제거하여 다른 기기의 세션에 영향을 주지 않도록 구현되었습니다.
123-124: 토큰 교체 로직이 적절합니다.사용된 리프레시 토큰을 새로운 토큰으로 교체하여 토큰 재사용을 방지합니다.
148-155: 프로필 업데이트 시 모든 토큰을 초기화하는 것은 적절한 보안 조치입니다.사용자 프로필이 변경되면 모든 기기에서 재로그인을 요구하여 보안을 강화합니다.
169-169: 비밀번호 재설정 시 모든 토큰 무효화는 보안 모범 사례입니다.비밀번호가 변경되면 모든 세션을 무효화하여 보안을 강화합니다.
backend/src/main/java/moadong/user/entity/User.java (3)
58-60: 리프레시 토큰 컬렉션 필드 선언이 적절합니다.
@Builder.Default를 사용하여 빈 리스트로 초기화하고, MongoDB 필드 매핑을 명시적으로 지정했습니다.
100-105: 토큰 추가 메서드가 안전하게 구현되었습니다.null 체크는
@Builder.Default로 초기화되어 있어 불필요해 보일 수 있지만, 레거시 데이터나 역직렬화 시나리오에서 방어적 코딩으로 작동합니다.
120-125: 토큰 제거 메서드가 깔끔하게 구현되었습니다.
removeIf를 사용하여 간결하고 읽기 쉬운 코드를 작성했습니다.
backend/src/main/java/moadong/user/service/UserCommandService.java
Outdated
Show resolved
Hide resolved
lepitaaar
left a comment
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.
refreshtoken 추가할때 레이스컨디션 이슈는 발생할꺼같은데 크리티컬하진 않은것 같습니다~ 리뷰하다 든생각인데 리프레시 토큰 리스트 길이 제한은 나중에 추가하는게 좋아보여요! 수고하셨습니다
#️⃣연관된 이슈
📝작업 내용
다중 리프레시 토큰 지원
고려했던 점
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
새로운 기능
개선 사항
✏️ Tip: You can customize this high-level summary in your review settings.