Skip to content

Conversation

@yoouyeon
Copy link
Contributor

@yoouyeon yoouyeon commented Nov 30, 2025

💻 작업 내용

카카오 로그인 로직을 추가했습니다!
백엔드쪽에 아직 카카오 로그인 기능이 잘 돌아가지 않는 것 같아서 우선은 로컬 서버와 msw로 프론트쪽 로직만 테스트했습니다!

로그인 로직은

  1. 로그인 페이지에서 카카오 로그인 버튼 클릭. 이 때 state 파라미터로 로그인 성공 후 돌아와야 하는 url 함께 전달
  2. 서버에서 로그인 처리 완료후 state로 전달한 url로 리다이렉트 시켜줌
  3. id "protected" 하위의 url들에 접근하기 전에는 "checkAuth" 로더를 거치게 됩니다!
    checkAuth 로더에서 유저 로그인 정보를 확인하고 (로그인 했는지, 아이디는 뭔지) 정상이라면 해당 페이지를 보여줌

이런 흐름입니다.

로컬 서버는 아래 코드를 node로 바로 실행하면 돼요 (express, cors 설치가 필요합니다)
환경변수도 VITE_KAKAO_REDIRECT_URI=http://localhost:8000/api/v1/login/oauth2/callback 로 리다이렉트 주소를 로컬호스트쪽으로 수정해줘야 합니당

const express = require("express");
const app = express();

app.get("/api/v1/login/oauth2/callback", (req, res) => {
  const { code, state } = req.query;

  // 로그인 프로세스...
  console.log("=== 요청 받음! ===");
  console.log("Code:", code);
  console.log("State:", state);
  // state로 즉시 리다이렉트
  res.redirect(decodeURIComponent(state));
});

app.listen(8000, () => {
  console.log("Mock server running on http://localhost:8000");
});

📸 스크린샷

Screen_Shot.2025-11-30.20.51.32.mov

👻 리뷰 요구사항 (선택)

제가 예전에 온보딩 페이지를 제거했었는데, 왜 제거했었는지 기억나지 않아서 🥹 일단 다시 되살려두었습니다.
혹시 온보딩 페이지를 제거해야 했던거라면 알려주세요..!!

Summary by CodeRabbit

릴리스 노트

  • New Features

    • Kakao OAuth 로그인 기능이 활성화되었습니다.
  • Improvements

    • 인증 플로우가 개선되어 보호된 경로에 더 안전한 접근 제어가 적용되었습니다.
    • 라우팅 구조가 재정리되어 앱의 네비게이션 환경이 향상되었습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

로그인이 필요한 경로들을 그룹화
- QueryClient를 queryClient.ts에서 관리하도록 변경
- QueryClient 기본 에러 핸들러를 설정할 수 있는 함수 추가
- 카카오 로그인 함수 분리
- 로그인 요청 시점의 state를 전달함 (리다이렉트용)
- 새로운 인증 체크 API 엔드포인트 추가
- 인증 체크를 위한 useGetAuth 훅 생성
- 인증 체크 Mock API 추가
2d11ed2 에서 제거한 온보딩 페이지 다시 추가
@yoouyeon yoouyeon self-assigned this Nov 30, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 30, 2025

Walkthrough

인증 인프라를 구축하고 라우팅을 재구성했습니다. 쿼리 클라이언트 설정을 외부로 분리하고, 비동기 인증 검증을 추가하며, Kakao OAuth 로그인 기능을 구현했습니다. 보호된 라우트 구조가 도입되어 라우트 접근 제어가 강화되었습니다.

Changes

내용 파일(들)
PR 템플릿
PR 제목 자동 생성에 대한 인라인 주석 추가
\.github/PULL_REQUEST_TEMPLATE\.md
쿼리 클라이언트 설정 리팩토링
useState 기반 QueryClient 초기화를 useEffect 기반 setupQueryClient로 변경; 쿼리 클라이언트 인스턴스를 공유 계층으로 외부화
src/app/App\.tsx, src/shared/api/queryClient\.ts
인증 API 및 로직
getAuth() 함수 추가, GuestTokenData 인터페이스 확장, checkAuth를 비동기로 변환하여 queryClient를 통해 사용자 데이터 조회
src/entities/auth/api/auth\.ts, src/entities/auth/lib/checkAuth\.ts
Kakao OAuth 로그인
새 kakaoLogin 모듈 추가 및 LoginPage에서 Kakao 로그인 기능 활성화
src/entities/auth/lib/kakaoLogin\.ts, src/pages/login/LoginPage\.tsx
인증 목 핸들러
GET /api/v1/user/auth/check 엔드포인트에 대한 MSW 목 핸들러 추가
src/mocks/handlers/auth\.ts
라우트 재구성
루트 경로 식별자 지정, 최상위 Suspense 추가, 보호된 부모 라우트 도입, 라우트 로더 통합
src/app/Router\.tsx

Possibly related PRs

  • README 추가 #4: 같은 src/Router.tsx 파일을 수정하는 PR로, 임포트 경로 업데이트 대 라우트 재구성 간의 코드 레벨 연관성이 있습니다.
  • .coderabbit.yaml 추가 및 설정 구성 #3: PR 자동 제목 동작과 관련된 PR로, 주 PR의 "@coderabbitai 제목" 주석과 같은 자동 제목 플레이스홀더 구성을 추가합니다.

Poem

🐰 쿼리 클라이언트를 정리하고,
라우트를 보호층으로 감싸니,
Kakao 로그인이 깡실 춤을 추네!
비동기 인증이 안전하게,
어딘가의 토끼도 웃음지어라! 🌙

Pre-merge checks and finishing touches

✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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 feat/MOD-71

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot requested a review from ongheong November 30, 2025 11:48
@yoouyeon yoouyeon added the ✨ Feature 신규 기능 추가 label Nov 30, 2025
@coderabbitai coderabbitai bot changed the title @coderabbitai 제목 인증 시스템 개선 및 카카오 로그인 추가 Nov 30, 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: 6

🧹 Nitpick comments (6)
src/mocks/handlers/auth.ts (1)

18-18: 개발용 로그 확인

디버깅용 console.log가 포함되어 있습니다. 개발 환경에서는 유용하지만, 프로덕션 빌드 전에 제거하거나 적절한 로깅 라이브러리로 전환하는 것을 고려해주세요.

src/entities/auth/lib/checkAuth.ts (2)

24-26: 주석 처리된 코드 정리 필요

리다이렉트 로직이 주석 처리되어 있습니다. 향후 구현할 예정이라면 TODO 주석으로 명확히 표시하거나, 구현하지 않을 예정이라면 제거하는 것이 좋습니다.

  } catch {
-   // NOTE - 로그인 성공 후 이전 페이지로 돌아가기 위한 로직
-   // const redirectTo = new URL(request.url).pathname;
-   // return redirect(`${ROUTE.login}?redirectTo=${redirectTo}`);
+   // TODO - 로그인 성공 후 이전 페이지로 돌아가기 위한 로직 구현 필요
+   // 구현 시 request.url에서 redirectTo를 추출하여 로그인 후 리다이렉트
    return redirect(ROUTE.login);
  }

11-16: 쿼리 설정 중복 확인

ensureQueryData에서 staleTimegcTime을 설정하고 있는데, useGetAuth 훅에서도 동일한 값으로 설정되어 있습니다. 쿼리 키 불일치 문제(이전에 지적됨)를 해결한 후, 한 곳에서만 이러한 설정을 관리하는 것을 고려해보세요.

src/shared/api/queryClient.ts (1)

18-18: QueryCache의 내부 API 직접 접근 방식 확인 필요.

queryClient.getQueryCache().config.onError를 직접 수정하는 방식은 내부 API에 접근하는 것으로, TanStack Query 버전 업그레이드 시 호환성이 보장되지 않을 수 있습니다. 권장 패턴은 QueryClient 생성 시 QueryCache를 명시적으로 전달하는 것입니다.

-import { QueryClient } from '@tanstack/react-query';
+import { QueryClient, QueryCache } from '@tanstack/react-query';

-export const queryClient = new QueryClient();
+let queryClient: QueryClient;

-export const setupQueryClient = (
+export const setupQueryClient = (
   handleQueryError: (error: Error) => void,
   handleMutationError: (error: Error) => void
 ) => {
+  queryClient = new QueryClient({
+    queryCache: new QueryCache({
+      onError: handleQueryError,
+    }),
+  });
   queryClient.setDefaultOptions({
     mutations: {
       onError: handleMutationError,
       throwOnError: true,
     },
     queries: {
       throwOnError: true,
     },
   });
-  queryClient.getQueryCache().config.onError = handleQueryError;
+  return queryClient;
 };
+
+export { queryClient };
src/app/Router.tsx (2)

52-113: createBrowserRouter를 컴포넌트 외부로 이동하는 것을 권장합니다.

현재 createBrowserRouter가 컴포넌트 함수 내부에서 호출되어, AppRouter가 렌더링될 때마다 라우터가 새로 생성됩니다. 이는 불필요한 재생성과 잠재적인 상태 손실을 유발할 수 있습니다. 라우터 정의를 컴포넌트 외부로 이동하거나, loader가 외부 의존성을 갖지 않는다면 모듈 스코프에서 생성하는 것이 좋습니다.


58-60: Suspense fallback UI 개선을 고려해 주세요.

현재 fallback이 <div>loading...</div>으로 설정되어 있습니다. 사용자 경험을 위해 스켈레톤 UI나 로딩 스피너 컴포넌트로 교체하는 것을 권장합니다.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 739f485 and c0e2788.

📒 Files selected for processing (10)
  • .github/PULL_REQUEST_TEMPLATE.md (1 hunks)
  • src/app/App.tsx (1 hunks)
  • src/app/Router.tsx (3 hunks)
  • src/entities/auth/api/auth.ts (2 hunks)
  • src/entities/auth/api/useGetAuth.ts (1 hunks)
  • src/entities/auth/lib/checkAuth.ts (1 hunks)
  • src/entities/auth/lib/kakaoLogin.ts (1 hunks)
  • src/mocks/handlers/auth.ts (1 hunks)
  • src/pages/login/LoginPage.tsx (2 hunks)
  • src/shared/api/queryClient.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
src/entities/auth/api/useGetAuth.ts (1)
src/entities/auth/api/auth.ts (1)
  • getAuth (18-23)
src/entities/auth/lib/checkAuth.ts (2)
src/shared/api/queryClient.ts (1)
  • queryClient (3-3)
src/entities/auth/api/auth.ts (1)
  • getAuth (18-23)
src/app/App.tsx (1)
src/shared/api/queryClient.ts (1)
  • setupQueryClient (5-19)
src/app/Router.tsx (1)
src/shared/config/route.ts (1)
  • ROUTE (3-12)
src/entities/auth/api/auth.ts (1)
public/mockServiceWorker.js (1)
  • response (125-125)
🔇 Additional comments (5)
.github/PULL_REQUEST_TEMPLATE.md (1)

1-1: 변경 사항 확인 완료

PR 템플릿에 CodeRabbit 자동 제목 생성 기능 안내가 추가되었습니다. 사용자에게 유용한 정보를 제공합니다.

src/entities/auth/lib/kakaoLogin.ts (1)

10-12: state 파라미터 인코딩 확인

encodeURIComponent를 사용하여 redirectUrl을 올바르게 인코딩하고 있습니다. 이는 URL 안전성을 보장하는 좋은 구현입니다.

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

7-8: Verify GuestTokenData interface compatibility

Confirm that the new expiredAt and isMember fields added to the GuestTokenData interface are either optional or that all consuming code has been updated to handle these fields. Check all usages of GuestTokenData throughout the codebase to ensure no type errors are introduced.


18-23: useMock configuration is properly supported and correctly implemented

The useMock: true option is a custom axios configuration that is fully supported via:

  1. TypeScript module augmentation in src/shared/types/axios.d.ts (extends AxiosRequestConfig with useMock?: boolean)
  2. Request interceptor in src/shared/api/axios.ts that handles this option by redirecting to the mock server and adding the X-Mock-Request: true header
  3. MSW handlers configured in src/mocks/handlers/auth.ts to respond to mocked requests

The getAuth function correctly uses this pattern and aligns with the project's mocking infrastructure.

src/app/App.tsx (1)

19-21: useEffect 의존성으로 인한 잠재적 재실행 문제

useApiError 훅에서 반환된 handleQueryErrorhandleMutationError를 의존성 배열에 포함하고 있습니다. 만약 이 함수들이 매 렌더링마다 새로운 참조를 생성한다면, setupQueryClient가 불필요하게 반복 호출될 수 있습니다.

useApiError 내부에서 useCallback을 사용하여 함수를 메모이제이션하고 있는지 확인이 필요합니다. 그렇지 않다면 성능 문제가 발생할 수 있습니다.

Outlet이 없어도 문제는 없었으나, 생략해도 된다는 문서를 찾지 못함...
모듈 로드 시점에 변수를 체크해서 에러 바운더리 쪽에서 처리할 수 있도록 함.
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/Router.tsx (1)

92-107: 라우트 보호 전략 개선 필요

createBill 라우트는 protected 라우트 구조 하위로 이동해야 합니다. 현재 getGroupManagerAuth 로더가 checkAuth의 로직을 중복 구현하고 있으며, 로더 코멘트에서도 "checkAuth와 중복됨"으로 표기되어 있습니다.

billDetailbillDetailCharacterShare 라우트는 URL의 groupToken 파라미터를 통해 공유 목적으로 인증 없이 접근 가능하도록 설계된 것으로 보이므로 현재 상태가 적절합니다.

권장사항:

  • createBillprotected 라우트 하위로 이동
  • getGroupManagerAuth 로더 제거 또는 기존 checkAuth 로더 재사용
🧹 Nitpick comments (1)
src/app/Router.tsx (1)

55-62: 로딩 폴백 UI 개선을 고려해보세요.

현재 "loading..." 텍스트만 표시되는데, 더 나은 사용자 경험을 위해 스피너나 스켈레톤 UI를 사용하는 것을 권장합니다.

예시:

-          <Suspense fallback={<div>loading...</div>}>
+          <Suspense fallback={<div className="loading-spinner">로딩 중...</div>}>
             <Outlet />
           </Suspense>
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0e2788 and 03d8cf0.

📒 Files selected for processing (3)
  • src/app/Router.tsx (3 hunks)
  • src/entities/auth/lib/kakaoLogin.ts (1 hunks)
  • src/mocks/handlers/auth.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/mocks/handlers/auth.ts
  • src/entities/auth/lib/kakaoLogin.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/Router.tsx (1)
src/shared/config/route.ts (1)
  • ROUTE (3-12)
🔇 Additional comments (2)
src/app/Router.tsx (2)

70-91: 이전 리뷰의 critical issue가 해결되었습니다!

Protected 라우트에 element: <Outlet />가 추가되어 자식 라우트들이 정상적으로 렌더링될 수 있습니다. 인증 로더와 함께 보호된 라우트 구조가 올바르게 구성되었습니다.


108-111: NotFound 라우트가 올바르게 구성되었습니다.

Catch-all 라우트(path: '*')가 children 배열의 마지막에 적절하게 배치되어 모든 미매칭 경로를 처리할 수 있습니다.

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.

Resolving thread - issue has been fixed

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.

2 participants