Skip to content

Conversation

@hamo-o
Copy link
Contributor

@hamo-o hamo-o commented Feb 15, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • Oauth 로그인 방식을
    • 쿠키에서 헤더에 넣어주는 방식으로 변경합니다. (쿠키 방식의 문제점: 클라이언트측에서 쿠키에 접근할 수 없도록 설정했기 때문에, 클라이언트에서 로그인 여부 확인을 위해서는 API 호출 또는 미들웨어 사용이 필요합니다. 또한 리다이렉트 역시 서버측에서 정해줘야 해서 서버-클라이언트 간 의존성이 생깁니다. )
    • 구글에서 리다이렉트 하는 URI를 서버측에서 클라이언트측으로 변경합니다. (더이상 토큰을 쿠키로 관리하지 않기 때문에, 클라이언트측에서 응답값으로 토큰을 받기 위함입니다.)
  • 로그인 여부에 따른 분기처리를 미들웨어가 아닌 tanstack router의 beforeLoad에서 처리합니다.

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

.local.env 세팅 이후 테스트 하셔야 합니다!

Summary by CodeRabbit

  • New Features

    • Streamlined login process: Clicking the Google login button now directly redirects you to the OAuth provider, seamlessly retrieving your access token.
    • Enhanced authentication flow: Protected pages now automatically check your login status, redirecting you appropriately.
    • New redirect component for OAuth handling, improving login flow and token retrieval.
  • Style & Navigation

    • Improved page layouts: Fixed positioning has been applied to discussion and calendar pages for uninterrupted and consistent viewing.
    • Updated routing structure for cleaner navigation and organization of routes.

@hamo-o hamo-o added the 🖥️ FE Frontend label Feb 15, 2025
@hamo-o hamo-o added this to the 3️⃣ 3차 스프린트 milestone Feb 15, 2025
@hamo-o hamo-o requested a review from dioo1461 as a code owner February 15, 2025 06:26
@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2025

Walkthrough

This pull request implements significant modifications to the authentication and routing logic, updates the login flow to use a JWT-based approach, refines the environment configuration, and adjusts certain UI layout styles. The middleware for access token verification is removed, while new API endpoints, hooks, and route definitions are introduced. In addition, model interfaces are updated, and JSX formatting is tweaked, ensuring that the overall control and navigation flow are altered consistently across authentication, routing, and UI components.

Changes

File(s) Change Summary
frontend/server/index.js, frontend/src/utils/auth/index.ts, frontend/src/utils/fetch/index.ts Removed middleware checking for an accessToken in the server; added the isLogin helper; updated fetch options by removing the BASE_URL constant and injecting an Authorization header using serviceENV.
frontend/src/features/login/api/index.ts, frontend/src/features/login/api/mutations.ts, frontend/src/features/login/model/index.ts, frontend/src/pages/LoginPage/index.tsx, frontend/src/routes/oauth.redirect/index.tsx, frontend/src/routes/oauth.redirect/index.lazy.tsx Refactored the login flow by replacing the requestGoogleLoginUrl function with a new loginApi.getJWT method, introducing the useJWTMutation hook, updating model interfaces (removing and renaming types), streamlining the LoginPage to use a direct OAuth link, and replacing the OAuth redirect component.
frontend/src/routeTree.gen.ts, frontend/src/routes/_main.tsx, frontend/src/routes/_main/discussion/create/$id.tsx, frontend/src/routes/_main/my-calendar/index.lazy.tsx, frontend/src/routes/index.tsx Updated the routing structure by removing/adding routes, revising route interfaces, introducing a beforeLoad function for authentication checks, changing route paths to include an _main prefix, and modifying redirection logic based on the user’s authentication status.
frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.css.ts, frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.tsx, frontend/src/pages/MyCalendarPage/index.css.ts Adjusted UI styling by adding CSS properties (position: fixed, top: 0, left: 0) to fix the layout positioning, and reformatted JSX code for consistency in the DiscussionCreateFinishPage component.
frontend/src/envconfig.ts Introduced a new frozen constant serviceENV that encapsulates environment variables for the API’s base URL and the Google OAuth URL.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant LP as LoginPage
    participant OAuth as OAuth Provider
    participant RD as Redirect Component
    participant API as Login API Server

    U->>LP: Clicks Google login button
    LP->>OAuth: Redirects via Link using OAuth URL
    OAuth->>U: Returns with code parameter in URL
    U->>RD: Browser loads /oauth/redirect/?code=XYZ
    RD->>API: POST /api/v1/login with code payload
    API-->>RD: Returns JWTResponse (accessToken)
    RD->>LocalStorage: Stores accessToken
    RD->>U: Navigates to last path or /home
Loading
sequenceDiagram
    participant U as User
    participant R as Route Loader
    participant A as isLogin()

    U->>R: Requests a protected route
    R->>A: Check if user is authenticated
    A-->>R: Returns true/false
    alt Authenticated
      R->>U: Loads requested page (/home)
    else Not Authenticated
      R->>U: Redirects to /login (or /landing)
    end
Loading

Possibly related PRs

  • [BE-Fix] 쿠키 삭제, 인증 헤더 사용으로 변경 #172: The changes in the main PR, which involve removing the middleware that checks for an accessToken, are related to the modifications in the retrieved PR that transition the authentication mechanism from cookies to an authorization header, as both affect how authentication is handled in the application.
  • [FE-Feat] 라우팅 정리 및 express 서버 세팅 #168: The changes in the main PR, which involve the removal of a middleware function that checks for an accessToken, are directly related to the modifications in the retrieved PR that also involve middleware handling for login logic based on cookies in the Express server setup.
  • [BE-Fix] 구글 로그인 시 프론트 엔드로 리다이렉션 하도록 수정 #151: The changes in the main PR, which involve the removal of authentication checks and the restructuring of login functionality, are related to the modifications in the retrieved PR that focus on redirecting users after a Google login and managing authentication tokens, as both affect the login flow and user authentication process.

Suggested labels

🛠️ BE, 🥲 HELP WANTED

Suggested reviewers

  • kwon204

Poem

I'm a bunny, hopping through the code so light,
Watching middleware vanish like shadows in the night.
New JWT hops in with a joyful little skip,
Fixed routes and layouts on a browser trip.
My carrot of code shines with every bright byte,
Bursting with glee in this refreshing delight!
🐰💻


🪧 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.

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.

@hamo-o hamo-o changed the title [FE-Feat] 로그인 토큰 클라이언트에서 관리하도록 변경 [FE-Feat] 로그인 토큰 쿠키가 아닌 헤더로 보내도록 변경 Feb 15, 2025
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: 8

🔭 Outside diff range comments (1)
frontend/src/utils/fetch/index.ts (1)

23-23: 🛠️ Refactor suggestion

Remove unnecessary credentials setting.

Since the authentication has been moved from cookies to JWT in headers, the credentials: 'include' setting is no longer needed.

   const defaultOptions: RequestInit = {
     headers,
     mode: 'cors',
-    // accessToken을 쿠키로 관리하기 위한 설정
-    credentials: 'include',
   };
🧹 Nitpick comments (7)
frontend/src/pages/LoginPage/index.tsx (2)

12-26: Streamline error handling for missing environment variable.

Currently, there's no fallback or error handling if serviceENV.VITE_GOOGLE_OAUTH_URL were undefined or empty. This could leave users unable to initiate the login flow if the environment is misconfigured. Consider adding a sanity check or fallback URL to improve resilience.

 const LoginPage = () => (
   <div className={backdropStyle}>
     <Modal
       description={`Google 계정으로 간편하게 가입...`}
       isOpen={true}
       subTitle='로그인/회원가입'
       title='언제만나 시작하기'
     >
       <Modal.Footer>
-        <GoogleLoginButton />
+        {serviceENV.VITE_GOOGLE_OAUTH_URL ? (
+          <GoogleLoginButton />
+        ) : (
+          <p>로그인 URL이 설정되지 않았습니다.</p>
+        )}
       </Modal.Footer>
     </Modal>
   </div>
 );

28-46: Confirm usage of direct link for login.

Using a direct link instead of a mutation simplifies the login process, but also removes the ability to handle errors (e.g., network failures, invalid code) before navigation. If you need more advanced control or error messaging down the road, consider migrating the logic back into a client-side function call or a dedicated login route.

frontend/src/utils/auth/index.ts (1)

1-1: Beware of storing tokens in local storage.

Placing tokens in local storage can expose them to XSS attacks, as JS code can read and modify local storage. For better security, consider using HttpOnly cookies or other approaches (e.g., rotating tokens, storing them in secure states) if feasible.

frontend/src/envconfig.ts (1)

5-8: Consider standardizing environment variable naming.

The environment variable naming is inconsistent:

  • BASE_URL uses a different naming convention than VITE_GOOGLE_OAUTH_URL
  • Both variables are accessed from import.meta.env.VITE_* but only one includes the VITE_ prefix in its property name
 export const serviceENV = Object.freeze({
-  BASE_URL: import.meta.env.VITE_API_URL,
+  API_URL: import.meta.env.VITE_API_URL,
   VITE_GOOGLE_OAUTH_URL: import.meta.env.VITE_GOOGLE_OAUTH_URL,
 });
frontend/src/features/login/api/index.ts (1)

1-12: Consider adding request timeout and retry logic.

For critical authentication endpoints, it's recommended to:

  • Add request timeout
  • Implement retry logic for transient failures
  • Add proper error types for different failure scenarios

Would you like me to provide an implementation example with these improvements?

frontend/src/routes/_main.tsx (1)

13-17: LGTM! Centralized authentication check implementation.

The beforeLoad hook effectively implements client-side authentication verification for all routes under '_main', aligning with the new token management approach.

Consider enhancing error handling.

The current implementation might benefit from more robust error handling:

  1. Handle potential network errors during isLogin check
  2. Consider adding a loading state
  beforeLoad: async () => {
-   if (!isLogin()) {
-     throw redirect({ to: '/login' });
-   }
+   try {
+     if (!isLogin()) {
+       throw redirect({ to: '/login' });
+     }
+   } catch (error) {
+     console.error('Authentication check failed:', error);
+     throw redirect({ to: '/login', search: { error: 'auth_check_failed' } });
+   }
  },
frontend/src/routes/oauth.redirect/index.tsx (1)

13-18: Prevent potential race conditions in useEffect.

The current implementation might trigger multiple mutations if dependencies change rapidly.

   useEffect(() => {
+    let isLatestRequest = true;
     const controller = new AbortController();
     
     if (code && !isPending) {
-      loginMutate({ code, lastPath }, { signal: controller.signal });
+      loginMutate(
+        { code, lastPath },
+        {
+          signal: controller.signal,
+          onSuccess: () => {
+            if (isLatestRequest) {
+              // Handle success
+            }
+          },
+        }
+      );
     }
-    return () => controller.abort();
+    return () => {
+      isLatestRequest = false;
+      controller.abort();
+    };
   }, [code, loginMutate, isPending, lastPath]);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fac74ec and 64bd97d.

📒 Files selected for processing (18)
  • frontend/server/index.js (0 hunks)
  • frontend/src/envconfig.ts (1 hunks)
  • frontend/src/features/login/api/index.ts (1 hunks)
  • frontend/src/features/login/api/mutations.ts (1 hunks)
  • frontend/src/features/login/model/index.ts (1 hunks)
  • frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.css.ts (1 hunks)
  • frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.tsx (1 hunks)
  • frontend/src/pages/LoginPage/index.tsx (1 hunks)
  • frontend/src/pages/MyCalendarPage/index.css.ts (1 hunks)
  • frontend/src/routeTree.gen.ts (17 hunks)
  • frontend/src/routes/_main.tsx (2 hunks)
  • frontend/src/routes/_main/discussion/create/$id.tsx (1 hunks)
  • frontend/src/routes/_main/my-calendar/index.lazy.tsx (1 hunks)
  • frontend/src/routes/index.tsx (1 hunks)
  • frontend/src/routes/oauth.redirect/index.lazy.tsx (0 hunks)
  • frontend/src/routes/oauth.redirect/index.tsx (1 hunks)
  • frontend/src/utils/auth/index.ts (1 hunks)
  • frontend/src/utils/fetch/index.ts (3 hunks)
💤 Files with no reviewable changes (2)
  • frontend/server/index.js
  • frontend/src/routes/oauth.redirect/index.lazy.tsx
✅ Files skipped from review due to trivial changes (1)
  • frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Send PR Notification to Reviewers
🔇 Additional comments (6)
frontend/src/features/login/model/index.ts (1)

1-7: Renamed and restructured interfaces look consistent.

Renaming to JWTRequest and JWTResponse clarifies their purpose. This is a clear and concise approach to describing the request and response data for JWT-based login.

frontend/src/pages/DiscussionPage/DiscussionCreateFinishPage/index.css.ts (1)

7-9: Verify fixed positioning impact on page layout.

Using position: fixed with full viewport dimensions could cause several issues:

  • Content may overlap with other fixed/absolute positioned elements
  • May break scrolling behavior on mobile devices
  • Could interfere with responsive design patterns

Consider using position: absolute or a different layout approach if the intent is to maintain the container within its parent element's flow.

frontend/src/routes/_main/my-calendar/index.lazy.tsx (1)

15-17: LGTM! Route path update aligns with authentication restructuring.

The route path change to include the '_main' prefix correctly places this route under the protected main layout, which is consistent with the new authentication flow.

frontend/src/routes/_main/discussion/create/$id.tsx (1)

15-17: LGTM! Route path update is consistent with authentication changes.

The route path modification to include '_main' prefix correctly places this route under the protected main layout.

frontend/src/pages/MyCalendarPage/index.css.ts (1)

9-11: Verify the layout implications of fixed positioning.

Setting position: fixed with top: 0 and left: 0 might cause the calendar to overlay other content or create scrolling issues, especially with the existing paddingTop: 56 and overflow: hidden properties.

frontend/src/routeTree.gen.ts (1)

85-89: LGTM! Route changes align with the new authentication flow.

The OAuth redirect route is correctly configured to handle the client-side token management.

Also applies to: 402-404

Copy link
Contributor

@dioo1461 dioo1461 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~~ 확실히 localStorage로 하니까 관리하기 편한 느낌이네요!

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 (1)
frontend/src/pages/LoginPage/index.tsx (1)

28-46:

Details

❓ Verification inconclusive

Verify OAuth configuration and redirect handling.

The direct navigation to Google OAuth looks good, but please ensure:

  1. The GOOGLE_OAUTH_URL is properly configured in .local.env as mentioned in the PR description
  2. The OAuth redirect URI is updated to handle the new header-based token approach

Let's verify the environment configuration:


🏁 Script executed:

#!/bin/bash
# Check if GOOGLE_OAUTH_URL is configured in .local.env
if [ -f "frontend/.local.env" ]; then
    echo "Checking .local.env configuration..."
    grep "GOOGLE_OAUTH_URL" frontend/.local.env
else
    echo "Warning: .local.env file not found in frontend directory"
fi

# Check for any remaining cookie-related code that might need updating
echo "Checking for remaining cookie-related code..."
rg -i "cookie" frontend/src

Length of output: 284


OAuth configuration verification required.

The Google login flow implementation looks correct regarding the direct navigation. However, note the following:

  • The expected environment file (frontend/.local.env) wasn’t found, so please verify whether GOOGLE_OAUTH_URL is defined elsewhere or if the file should be added to ensure proper configuration.
  • Confirm that the OAuth redirect URI is updated to support the new header-based token approach.
  • Ensure that no residual cookie-related logic remains that might interfere with the authentication flow.
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 64bd97d and e74cdab.

📒 Files selected for processing (2)
  • frontend/src/envconfig.ts (1 hunks)
  • frontend/src/pages/LoginPage/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/envconfig.ts
🔇 Additional comments (2)
frontend/src/pages/LoginPage/index.tsx (2)

1-8: LGTM! Import changes align with the new authentication approach.

The changes correctly reflect the shift from API-based login to direct OAuth navigation.


12-26: LGTM! Component successfully simplified.

The LoginPage component has been streamlined by removing unnecessary mutation logic while maintaining the core UI structure.

@hamo-o hamo-o merged commit b358396 into dev Feb 16, 2025
1 check passed
@hamo-o hamo-o deleted the feature/fe/login-header branch February 16, 2025 04:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🖥️ FE Frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants