Skip to content

[Feature/#37] 토큰 재발급 로직 구현#40

Merged
wjdrjs00 merged 4 commits intodevelopfrom
feature/#37-token-refresh
Jul 23, 2025
Merged

[Feature/#37] 토큰 재발급 로직 구현#40
wjdrjs00 merged 4 commits intodevelopfrom
feature/#37-token-refresh

Conversation

@wjdrjs00
Copy link
Copy Markdown
Member

@wjdrjs00 wjdrjs00 commented Jul 23, 2025

[ PR Content ]

api 호출 시 401 응답을 받을 경우 자동으로 토큰을 재발급하고 요청을 재시도하는 로직을 구현했습니다요~
추가로 기존 API 호출 에러 처리 로직도 같이 개선했습니다!

Related issue

Screenshot 📸

  • N/A

Work Description

토큰 재발급 로직 구현

  • 401 Unauthorized 응답 시 자동 토큰 갱신
  • Mutex를 통한 동시성 제어로 중복 갱신 방지
  • 최대 2회 재시도로 무한 루프 방지

API 에러 처리 개선 (safeApiCall)

  • 기존 safeApiCall의 Unit 타입 처리 문제 해결
  • safeUnitApiCall 추가로 반환값이 없는 API 호출 지원

To Reviewers 📢

  • 현재 작업에서는 토큰 만료 시 MainActivity로 이동하도록 구현되어 있는데, 네비게이션로직이 구축된 후 따로 이벤트 기반 토큰 만료 처리로 리펙토링 하려고 생각중입니다!
  • 기존 safeApiCall 에서 Unit 반환 API의 경우 response.data가 null이어서 failure로 처리되는 문제 발생했는데, 이를 새로운 Response 타입 정의 없이 safeUnitApiCall로 깔쌈하게 해결해봤습니다.

Summary by CodeRabbit

  • 신규 기능

    • 액세스 토큰 만료 시 자동으로 토큰을 갱신하고, 갱신 실패 시 메인 화면으로 이동하는 기능이 추가되었습니다.
    • 토큰 재발급을 위한 네트워크 서비스가 도입되었습니다.
  • 버그 수정

    • API 호출 시 오류 응답 처리 및 에러 메시지 제공이 개선되었습니다.
  • 리팩터링

    • 토큰 관리 및 인증 처리 로직이 구조적으로 개선되어 동기화 및 예외 처리가 강화되었습니다.
  • 문서화

    • 데이터 모델 및 네트워크 인터페이스에 대한 설명이 추가되었습니다.

wjdrjs00 added 4 commits July 23, 2025 11:53
- AuthToken 데이터 클래스 추가
- Unit을 반환하는 API 호출을 위한 safeUnitApiCall 메소드 추가
- API 예외 처리를 위한 handleApiException 메소드 재사용성을 위해 분리
@wjdrjs00 wjdrjs00 requested a review from l5x5l July 23, 2025 03:56
@wjdrjs00 wjdrjs00 self-assigned this Jul 23, 2025
@wjdrjs00 wjdrjs00 added ✨ Feature 새로운 기능 구현 🧤 대현 labels Jul 23, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 23, 2025

Walkthrough

토큰 재발급 및 만료 처리 기능이 네트워크 계층에 도입되었습니다. TokenProvider와 TokenAuthenticator가 확장되어 토큰 저장, 갱신, 삭제가 가능해졌으며, 토큰 만료 시 메인 액티비티로 이동하는 콜백이 추가되었습니다. 또한, ReissueService와 AuthToken 모델이 새로 도입되었고, SafeApiCall의 예외 처리 로직이 개선되었습니다.

Changes

파일/경로 변경 요약
.../NetworkModule.kt, .../ServiceModule.kt NetworkModule: TokenProvider 확장, TokenAuthenticator 및 토큰 재발급 로직 DI에 추가
ServiceModule: ReissueService DI에 추가
.../TokenAuthenticator.kt TokenAuthenticator 리팩토링: 동기화된 토큰 갱신, 만료 콜백 추가, 에러 처리 구조화
.../TokenProvider.kt TokenProvider 인터페이스에 토큰 저장/갱신/삭제 메서드 추가
.../ReissueService.kt Retrofit 기반 ReissueService 인터페이스 신규 추가
.../AuthToken.kt AuthToken 데이터 클래스 신규 추가
.../SafeApiCall.kt safeApiCall 리팩토링, safeUnitApiCall 및 예외 처리 함수 추가, 에러 파싱 개선

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant OkHttpClient
    participant TokenAuthenticator
    participant TokenProvider
    participant ReissueService
    participant MainActivity

    App->>OkHttpClient: API 요청
    OkHttpClient-->>TokenAuthenticator: 401 Unauthorized 응답
    TokenAuthenticator->>TokenProvider: getAccessToken / getRefreshToken
    alt Refresh token 존재
        TokenAuthenticator->>ReissueService: reissueToken(Refresh-Token)
        alt 재발급 성공
            ReissueService-->>TokenAuthenticator: 새 access, refresh 토큰
            TokenAuthenticator->>TokenProvider: saveTokens
            TokenAuthenticator-->>OkHttpClient: 새 accessToken으로 재시도
        else 재발급 실패
            TokenAuthenticator->>TokenProvider: clearTokens
            TokenAuthenticator->>MainActivity: onTokenExpired 콜백 (스택 클리어)
        end
    else Refresh token 없음
        TokenAuthenticator->>TokenProvider: clearTokens
        TokenAuthenticator->>MainActivity: onTokenExpired 콜백 (스택 클리어)
    end
Loading

Estimated code review effort

4 (~90분)

Possibly related PRs

Suggested reviewers

  • l5x5l

Poem

토큰이 만료되어도 걱정 마세요
토끼가 깡총 뛰어 리프레시해요
새로운 키로 문을 열고
실패하면 깔끔히 정리하고
메인으로 점프!
🐇✨
네트워크는 이제 더 든든해요!

✨ 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
Copy Markdown

@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 (2)
core/network/src/main/java/com/threegap/bitnagil/network/model/AuthToken.kt (1)

6-14: AuthToken 데이터 클래스가 잘 구현되었습니다.

직렬화 설정과 JSON 매핑이 적절하게 구성되어 있습니다. role 프로퍼티 제거 TODO를 추적하여 향후 정리하시기 바랍니다.

role 프로퍼티 제거를 위한 이슈를 생성하거나 리팩토링 계획을 수립하는데 도움이 필요하시면 말씀해 주세요.

data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt (1)

39-46: 예외 처리 개선이 필요합니다.

JSON 파싱 실패 시 예외를 삼키고 있어 디버깅이 어려울 수 있습니다.

로깅을 추가하여 파싱 실패 원인을 추적할 수 있도록 개선을 고려해보세요:

private fun parseErrorResponse(errorBody: String?): ErrorResponse? =
    errorBody?.let {
        try {
            json.decodeFromString<ErrorResponse>(it)
        } catch (e: Exception) {
+           // 로깅 또는 디버그 정보 추가 고려
            null
        }
    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fc18fe and 707fe8e.

📒 Files selected for processing (7)
  • app/src/main/java/com/threegap/bitnagil/di/core/NetworkModule.kt (3 hunks)
  • app/src/main/java/com/threegap/bitnagil/di/data/ServiceModule.kt (2 hunks)
  • core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt (2 hunks)
  • core/network/src/main/java/com/threegap/bitnagil/network/model/AuthToken.kt (1 hunks)
  • core/network/src/main/java/com/threegap/bitnagil/network/token/ReissueService.kt (1 hunks)
  • core/network/src/main/java/com/threegap/bitnagil/network/token/TokenProvider.kt (1 hunks)
  • data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt (1 hunks)
🧠 Learnings (6)
📓 Common learnings
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
core/network/src/main/java/com/threegap/bitnagil/network/token/TokenProvider.kt (1)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/token/ReissueService.kt (1)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/model/AuthToken.kt (2)

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

app/src/main/java/com/threegap/bitnagil/di/core/NetworkModule.kt (2)

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt (2)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

🪛 detekt (1.23.8)
data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt

[warning] 43-43: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
Learnt from: wjdrjs00
PR: YAPP-Github/Bitnagil-Android#25
File: presentation/src/main/java/com/threegap/bitnagil/presentation/splash/SplashViewModel.kt:50-65
Timestamp: 2025-07-11T03:54:23.348Z
Learning: AuthTokenDataStoreImpl.hasToken() 메소드에서 예외 발생 시 false를 반환하도록 이미 예외 처리가 구현되어 있어, 상위 레이어에서 추가적인 예외 처리가 불필요합니다.
core/network/src/main/java/com/threegap/bitnagil/network/token/TokenProvider.kt (1)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/token/ReissueService.kt (1)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/model/AuthToken.kt (2)

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

app/src/main/java/com/threegap/bitnagil/di/core/NetworkModule.kt (2)

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt (2)

Learnt from: wjdrjs00
PR: #19
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:16-20
Timestamp: 2025-07-06T04:26:03.870Z
Learning: TokenAuthenticator 클래스는 현재 임시 코드로 구현되어 있으며, 실제 토큰 재발급 API 연동 시점에 올바른 구현으로 수정될 예정입니다.

Learnt from: wjdrjs00
PR: #16
File: core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt:12-46
Timestamp: 2025-07-03T09:05:30.067Z
Learning: 이 프로젝트에서는 네트워크 모듈을 점진적으로 개발하고 있으며, TokenAuthenticator 같은 인증 관련 기능은 실제 API 연동 작업 시점에 NetworkModule에 연결할 예정입니다.

🪛 detekt (1.23.8)
data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt

[warning] 43-43: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (16)
core/network/src/main/java/com/threegap/bitnagil/network/token/TokenProvider.kt (1)

5-7: 인터페이스 확장이 잘 구현되었습니다.

토큰 생명주기 관리를 위한 새로운 메서드들이 적절하게 추가되었습니다. suspend 키워드 사용과 메서드 네이밍이 일관성 있고 명확합니다.

app/src/main/java/com/threegap/bitnagil/di/data/ServiceModule.kt (2)

6-7: 필요한 import가 올바르게 추가되었습니다.

NoneAuth와 ReissueService import가 적절합니다.


29-32: ReissueService DI 설정이 올바릅니다.

토큰 재발급 API는 인증이 필요하지 않으므로 @NoneAuth Retrofit 인스턴스를 사용하는 것이 적절합니다. 기존 패턴을 잘 따르고 있습니다.

core/network/src/main/java/com/threegap/bitnagil/network/token/ReissueService.kt (1)

8-13: ReissueService 인터페이스가 깔끔하게 구현되었습니다.

토큰 재발급 API 설계가 적절합니다. Refresh-Token을 헤더로 전달하고 BaseResponse을 반환하는 구조가 일관성 있습니다.

data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt (3)

10-25: safeApiCall 리팩토링이 잘 되었습니다.

표현식 바디 사용과 예외 처리 로직 분리가 코드를 더 깔끔하게 만들었습니다. HTTP 응답 코드를 포함한 에러 코드 개선도 디버깅에 도움이 될 것입니다.


27-35: safeUnitApiCall 함수 추가가 적절합니다.

PR 목표에서 언급한 Unit 타입 API 호출이 실패로 처리되는 문제를 해결하는 좋은 접근방식입니다. Unit 반환 API를 위한 전용 함수가 필요했습니다.


48-68: 예외 처리 로직이 체계적으로 구현되었습니다.

HttpException, IOException, 기타 예외들을 적절히 분류하여 처리하고 있습니다. 에러 응답 파싱과 fallback 메시지 제공이 잘 구현되어 있습니다.

app/src/main/java/com/threegap/bitnagil/di/core/NetworkModule.kt (4)

3-10: import 구성이 적절합니다.

토큰 만료 처리를 위한 필요한 import들이 잘 추가되었습니다. MainActivity에 대한 직접적인 의존성은 PR 설명에 따르면 네비게이션 로직이 확립된 후 이벤트 기반으로 리팩토링 예정이므로 현재로서는 적절합니다.


65-75: TokenProvider 구현이 잘 확장되었습니다.

리프레시 토큰 관리를 위한 필수 메서드들이 적절히 구현되었습니다. dataStore를 통한 토큰 저장/조회/삭제 로직이 올바르게 처리되고 있습니다.


77-94: TokenAuthenticator 제공 메서드가 올바르게 구현되었습니다.

토큰 만료 시 MainActivity로 이동하는 콜백이 적절한 플래그와 함께 구현되었습니다. PR 설명에 따르면 이는 임시 구현이며 추후 이벤트 기반으로 리팩토링될 예정입니다.


105-116: OkHttpClient에 TokenAuthenticator가 올바르게 통합되었습니다.

401 응답 시 자동 토큰 재발급을 위한 authenticator 설정이 적절히 추가되었습니다.

core/network/src/main/java/com/threegap/bitnagil/network/auth/TokenAuthenticator.kt (5)

13-19: TokenAuthenticator가 실제 토큰 재발급 로직으로 올바르게 구현되었습니다.

이전 학습 내용에 따르면 임시 구현이었던 TokenAuthenticator가 이제 TokenProvider, ReissueService와 함께 적절히 통합되었습니다. Mutex를 사용한 동시성 제어도 잘 구현되었습니다.


21-36: authenticate 메서드의 토큰 비교 및 동기화 로직이 우수합니다.

현재 저장된 토큰과 요청의 토큰을 비교하여 불필요한 재발급을 방지하고, Mutex를 통해 동시 재발급 요청을 올바르게 제어합니다.


38-66: refreshAndRetry 메서드의 에러 처리가 견고합니다.

리프레시 토큰 유효성 검사, API 호출 실패 처리, 응답 코드 검증이 모두 적절히 구현되었습니다. 모든 실패 케이스에서 일관되게 토큰 만료 처리가 수행됩니다.


78-91: 헬퍼 메서드들이 명확하고 올바르게 구현되었습니다.

재시도 횟수 제한(2회), Bearer 토큰 헤더 생성, 토큰 만료 처리가 모두 적절합니다. PR 목표에 명시된 무한 루프 방지가 잘 구현되었습니다.


93-99: 상수 정의가 적절합니다. SUCCESS_CODE 확인 필요.

HTTP 상태 코드와 Bearer 토큰 형식이 표준을 따르고 있습니다. SUCCESS_CODE "CO000"이 백엔드 API 명세와 일치하는지 확인하시기 바랍니다.

Comment thread data/src/main/java/com/threegap/bitnagil/data/common/SafeApiCall.kt
Copy link
Copy Markdown
Contributor

@l5x5l l5x5l left a comment

Choose a reason for hiding this comment

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

마지막까지 확인해주시느라 고생하셨습니다!

@wjdrjs00 wjdrjs00 merged commit c5e853f into develop Jul 23, 2025
2 checks passed
@wjdrjs00 wjdrjs00 deleted the feature/#37-token-refresh branch July 23, 2025 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능 구현 🧤 대현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 토큰 재발급 로직 구현

2 participants