Skip to content

Conversation

@young-jin-son
Copy link
Collaborator

@young-jin-son young-jin-son commented Jul 17, 2025

Issue Number

close #302

As-Is

토큰 재발급 처리 안됐음

To-Be

  • 토큰 재발급 처리 로직 추가

Check List

  • 테스트가 전부 통과되었나요?
  • 모든 commit이 push 되었나요?
  • merge할 branch를 확인했나요?
  • Assignee를 지정했나요?
  • Label을 지정했나요?

Test Screenshot

(Optional) Additional Description

Summary by CodeRabbit

  • New Features

    • Centralized authentication and token management, including login, logout, token refresh, and account deletion.
    • Unified navigation handling for authentication states.
  • Refactor

    • Replaced multiple authentication-related modules with a single, consolidated module for easier maintenance.
    • Updated all authentication logic to use new centralized managers for tokens and navigation.
    • Renamed the login button component and updated its usage across the app.
  • Bug Fixes

    • Improved error handling for authentication failures and token refresh scenarios.

@young-jin-son young-jin-son self-assigned this Jul 17, 2025
@young-jin-son young-jin-son added fix 버그 수정 (기능을 잘못 구현한 경우) feat 새로운 기능 구현 FE 프론트엔드 작업 labels Jul 17, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 17, 2025

Walkthrough

The changes consolidate authentication logic into a new auth.ts module, centralizing token management, OAuth login, logout, and account deletion. Related hooks and components are updated to use this module, removing direct localStorage and navigation logic. The fetch client is enhanced to handle token refresh on 401 errors using the new abstractions.

Changes

File(s) Change Summary
frontend/src/api/auth.ts New module: Centralizes token management, OAuth login, logout, account deletion, and navigation logic.
frontend/src/api/login.ts, frontend/src/api/logout.ts, frontend/src/api/deleteAccount.ts Deleted: Old separate modules for login, logout, and account deletion removed in favor of unified auth module.
frontend/src/api/fetchClient.ts Enhanced: Now uses tokenManager for tokens, handles 401 by refreshing token and retrying, uses redirectManager.
frontend/src/components/Button/DeleteAccountButton/hooks/deleteAccountMutation.ts Refactored: Uses tokenManager and redirectManager for token removal and navigation after account deletion.
frontend/src/components/Button/LoginButton/index.tsx Refactored: Renamed component to LoginButton, uses new kakaoLogin from auth module.
frontend/src/components/Button/LogoutButton/hooks/useLogoutMutation.ts Refactored: Uses tokenManager and redirectManager for logout handling and navigation.
frontend/src/pages/KakaoLoginPage/hooks/useKakaoLoginMutation.tsx Refactored: Uses tokenManager and redirectManager for login, token storage, and navigation.
frontend/src/pages/LandingPage/components/ServiceGuide/GuideIntro/index.tsx Refactored: Uses new LoginButton component.
frontend/src/pages/LandingPage/components/ServiceGuide/GuideOutro/index.tsx Refactored: Uses new LoginButton component.
frontend/src/pages/LandingPage/components/ServiceGuide/GuideSlide/index.tsx Refactored: Uses new LoginButton component.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LoginButton
    participant auth.ts
    participant Backend

    User->>LoginButton: Clicks Login
    LoginButton->>auth.ts: kakaoLogin()
    auth.ts->>User: Redirects to Kakao OAuth

    User->>auth.ts: Returns with code
    auth.ts->>Backend: POST /kakao-login (with code)
    Backend-->>auth.ts: Returns access token
    auth.ts->>auth.ts: tokenManager.set(token)
    auth.ts->>auth.ts: redirectManager.toOnboarding()
Loading
sequenceDiagram
    participant AnyAPIRequest
    participant fetchClient
    participant auth.ts
    participant Backend

    AnyAPIRequest->>fetchClient: request()
    fetchClient->>auth.ts: tokenManager.get()
    fetchClient->>Backend: API request with token
    Backend-->>fetchClient: 401 Unauthorized
    fetchClient->>auth.ts: tokenManager.refresh()
    alt Refresh succeeds
        auth.ts->>Backend: POST /reissue
        Backend-->>auth.ts: New token
        auth.ts->>auth.ts: tokenManager.set(new token)
        fetchClient->>Backend: Retry API request with new token
        Backend-->>fetchClient: Success
    else Refresh fails
        auth.ts->>auth.ts: tokenManager.remove()
        auth.ts->>auth.ts: redirectManager.toLanding()
        fetchClient-->>AnyAPIRequest: Throws error
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Handle token refresh on login expiration (401) (#302)
Centralize and abstract token management and navigation (#302)

Possibly related PRs

Suggested reviewers

  • rbgksqkr

Poem

In the warren of code, a change hops through,
Tokens now managed with logic anew.
Logins and logouts, all in one place,
No more scattered, a unified space.
🐇 With a hop and a skip, auth flows are refined,
Simpler for users, and easier to mind!

✨ 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
Contributor

@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 (4)
frontend/src/components/Button/DeleteAccountButton/hooks/deleteAccountMutation.ts (1)

3-3: Auth consolidation looks good, but has redundant token removal.

The centralized auth module usage is a good improvement. However, there's redundant token removal since redirectManager.toLanding() already calls tokenManager.remove() internally.

Consider removing the redundant token removal:

    onSuccess: () => {
-      tokenManager.remove();
      redirectManager.toLanding();
    },

The redirectManager.toLanding() method handles both token removal and redirection as seen in frontend/src/api/auth.ts.

Also applies to: 9-11

frontend/src/components/Button/LogoutButton/hooks/useLogoutMutation.ts (1)

3-3: Auth consolidation implemented consistently, but has redundant token removal.

The centralized auth module usage is consistent with the previous file. However, the same redundant token removal issue exists since redirectManager.toLanding() already handles token cleanup internally.

Consider removing the redundant token removal:

    onSuccess: () => {
-      tokenManager.remove();
      redirectManager.toLanding();
    },

This matches the pattern that should be used consistently across both logout and delete account flows.

Also applies to: 9-11

frontend/src/api/auth.ts (2)

75-87: Consider adding error handling for logout requests.

The logout function correctly includes the Authorization header, but doesn't handle potential network errors or API failures.

Consider adding basic error handling:

export const logout = async () => {
  const accessToken = tokenManager.get();

  if (accessToken) {
-    await fetch(API_URL.logout, {
-      method: 'POST',
-      headers: {
-        'Content-Type': 'application/json',
-        Authorization: `Bearer ${accessToken}`,
-      },
-    });
+    try {
+      await fetch(API_URL.logout, {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+          Authorization: `Bearer ${accessToken}`,
+        },
+      });
+    } catch (error) {
+      // Log error but don't throw - logout should be best effort
+      console.warn('Logout request failed:', error);
+    }
  }
};

89-101: Consider adding error handling for account deletion.

Similar to the logout function, the account deletion doesn't handle potential failures.

Consider adding error handling:

export const deleteAccount = async () => {
  const accessToken = tokenManager.get();

  if (accessToken) {
-    await fetch(API_URL.deleteAccount, {
-      method: 'DELETE',
-      headers: {
-        'Content-Type': 'application/json',
-        Authorization: `Bearer ${accessToken}`,
-      },
-    });
+    try {
+      const response = await fetch(API_URL.deleteAccount, {
+        method: 'DELETE',
+        headers: {
+          'Content-Type': 'application/json',
+          Authorization: `Bearer ${accessToken}`,
+        },
+      });
+      
+      if (!response.ok) {
+        const error = await response.json();
+        throw error;
+      }
+    } catch (error) {
+      // Account deletion failures should be handled by the caller
+      throw error;
+    }
  }
};
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cfef467 and 59b61a7.

📒 Files selected for processing (12)
  • frontend/src/api/auth.ts (1 hunks)
  • frontend/src/api/deleteAccount.ts (0 hunks)
  • frontend/src/api/fetchClient.ts (3 hunks)
  • frontend/src/api/login.ts (0 hunks)
  • frontend/src/api/logout.ts (0 hunks)
  • frontend/src/components/Button/DeleteAccountButton/hooks/deleteAccountMutation.ts (1 hunks)
  • frontend/src/components/Button/LoginButton/index.tsx (2 hunks)
  • frontend/src/components/Button/LogoutButton/hooks/useLogoutMutation.ts (1 hunks)
  • frontend/src/pages/KakaoLoginPage/hooks/useKakaoLoginMutation.tsx (1 hunks)
  • frontend/src/pages/LandingPage/components/ServiceGuide/GuideIntro/index.tsx (1 hunks)
  • frontend/src/pages/LandingPage/components/ServiceGuide/GuideOutro/index.tsx (2 hunks)
  • frontend/src/pages/LandingPage/components/ServiceGuide/GuideSlide/index.tsx (2 hunks)
💤 Files with no reviewable changes (3)
  • frontend/src/api/logout.ts
  • frontend/src/api/deleteAccount.ts
  • frontend/src/api/login.ts
🧰 Additional context used
🧬 Code Graph Analysis (5)
frontend/src/components/Button/LogoutButton/hooks/useLogoutMutation.ts (1)
frontend/src/api/auth.ts (3)
  • logout (75-87)
  • tokenManager (7-34)
  • redirectManager (36-49)
frontend/src/pages/KakaoLoginPage/hooks/useKakaoLoginMutation.tsx (2)
frontend/src/types/auth.ts (1)
  • KakaoLogin (1-5)
frontend/src/api/auth.ts (3)
  • kakaoLoginAuth (56-73)
  • tokenManager (7-34)
  • redirectManager (36-49)
frontend/src/components/Button/DeleteAccountButton/hooks/deleteAccountMutation.ts (1)
frontend/src/api/auth.ts (3)
  • deleteAccount (89-101)
  • tokenManager (7-34)
  • redirectManager (36-49)
frontend/src/api/fetchClient.ts (2)
frontend/src/api/auth.ts (2)
  • tokenManager (7-34)
  • redirectManager (36-49)
frontend/src/api/error.ts (1)
  • CustomError (14-24)
frontend/src/api/auth.ts (2)
frontend/src/constants/url.ts (1)
  • API_URL (5-77)
frontend/src/types/auth.ts (1)
  • KakaoLogin (1-5)
🔇 Additional comments (13)
frontend/src/pages/LandingPage/components/ServiceGuide/GuideIntro/index.tsx (1)

7-7: Clean component replacement as part of auth consolidation.

The replacement of KakaoLoginButton with LoginButton is consistent with the broader authentication refactor. The import path and usage are correct.

Also applies to: 15-15

frontend/src/pages/LandingPage/components/ServiceGuide/GuideSlide/index.tsx (1)

5-5: Consistent component replacement.

The LoginButton replacement follows the same clean pattern as other components in this refactor.

Also applies to: 26-26

frontend/src/pages/LandingPage/components/ServiceGuide/GuideOutro/index.tsx (1)

6-6: Systematic component replacement completed.

The LoginButton replacement is consistent across all landing page guide components, completing the systematic refactor.

Also applies to: 16-16

frontend/src/components/Button/LoginButton/index.tsx (1)

1-23: Clean refactoring to use centralized authentication module.

The component renaming from KakaoLoginButton to LoginButton and the import path updates are consistent with the centralization of authentication logic. The functionality remains intact while improving modularity.

frontend/src/pages/KakaoLoginPage/hooks/useKakaoLoginMutation.tsx (1)

3-18: Excellent refactoring to use centralized authentication managers.

The migration from direct localStorage access and useNavigate to tokenManager and redirectManager improves separation of concerns and centralizes authentication logic. The flow remains correct: token storage on success, appropriate redirects on both success and error cases.

frontend/src/api/fetchClient.ts (3)

1-1: Good centralization of token management.

Using tokenManager and redirectManager from the centralized auth module improves consistency across the application.


16-20: Well-designed method signature for retry handling.

The addition of the isRetry parameter with a default value of false is a clean way to track retry attempts and prevent infinite loops.


41-50: Excellent implementation of token refresh logic.

This correctly addresses the PR objective of handling token reissuance on login expiration. The implementation:

  • Checks for 401 status and ensures it's not already a retry
  • Attempts token refresh via tokenManager.refresh()
  • Retries the original request once if refresh succeeds
  • Redirects to landing page and throws error if refresh fails

The retry mechanism prevents infinite loops while ensuring proper token lifecycle management.

frontend/src/api/auth.ts (5)

4-5: Environment variable usage looks correct.

The Kakao client ID and redirect URI are properly imported from environment variables for OAuth configuration.


36-49: Good separation of navigation concerns.

The redirectManager centralizes navigation logic and properly removes tokens when redirecting to the landing page, ensuring clean authentication state transitions.


51-54: Kakao OAuth URL construction is correct.

The OAuth authorization URL is properly constructed using the required parameters for Kakao's OAuth flow.


56-73: Solid authentication code exchange implementation.

The kakaoLoginAuth function correctly exchanges the authorization code for tokens with proper error handling and response parsing.


7-34: Confirm cookie-based refresh flow

A search across the codebase shows no other calls to API_URL.authReissue sending an Authorization header—tokenManager.refresh() in frontend/src/api/auth.ts only sets Content-Type. This implies the endpoint relies on HTTP-only cookies rather than a bearer token.

• frontend/src/api/auth.ts: refresh() sends only Content-Type
• No other authReissue usages include an Authorization header

Please verify with the backend or API documentation that /api/v1/auth/reissue is indeed a cookie-based refresh endpoint and does not require passing the existing token in the header.

@young-jin-son young-jin-son merged commit b03ddc3 into develop Jul 17, 2025
3 checks passed
@young-jin-son young-jin-son deleted the fix/#302 branch July 17, 2025 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FE 프론트엔드 작업 feat 새로운 기능 구현 fix 버그 수정 (기능을 잘못 구현한 경우)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 로그인 만료 시 토큰 재발급 처리

2 participants