Skip to content

[FEAT] 로그인 api 연동 #50

Merged
wlsldm merged 13 commits into
devfrom
feat/49-login-api
Jul 27, 2026
Merged

[FEAT] 로그인 api 연동 #50
wlsldm merged 13 commits into
devfrom
feat/49-login-api

Conversation

@wlsldm

@wlsldm wlsldm commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

📍PR 유형 (하나 이상 선택)

  • 새로운 기능 추가
  • 버그 수정
  • CSS 등 사용자 UI 디자인 변경
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 테스트 추가, 테스트 리팩토링
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

‼️ 관련 이슈

resolves #49

👩🏻‍💻 작업 사항

  • 인스턴스 분리: 토큰이 필요 없는 publicInstance 과 필요한 authInstance로 분리

  • interceptor

    • 요청 인터셉터: authInstanceAuthorization: Bearer 자동 첨부
    • 응답 인터셉터: 401이면 토큰 재발급 후 원요청 재시도, 재발급까지 실패하면 토큰 정리 + 로그인 페이지 이동
      • 동시에 401이 여러 개 떠도 재발급 요청은 한 번만 나가도록 처리
      • isRetried 플래그로 재시도 무한 루프 차단
  • zustand + persist로 accessToken / refreshToken 관리

  • react-query 기본 설정

    • 4xx는 재시도하지 않고 네트워크 오류·5xx만 1회 재시도
  • ProtectedRoute: 토큰 없으면 /login으로 이동

  • PublicRoute: 토큰 있으면 /home으로 이동 (온보딩·로그인·회원가입·비밀번호 재설정에 적용)

  • 로그인 성공 시 토큰 저장 후 홈으로 이동, 요청 중 제출 버튼 비활성화

  • 로그아웃은 API 실패 여부와 관계없이 클라이언트 토큰을 정리하고 쿼리 캐시 제거 (onSettled)

    • 토큰이 비워지면 ProtectedRoute가 로그인 페이지로 보냄

📸 스크린샷

📢 기타(공유 사항)

  • 로그인 실패 메시지가 현재 임시 alert 으로 구현해뒀습니다! 디자인과 논의하여 실패 메세지 어떻게 띄울지 정해야할 것 같습니다

Summary by CodeRabbit

  • 새로운 기능
    • 로그인/로그아웃을 API와 React Query로 연동했습니다.
    • 기숙사 본인확인 정보 조회 및 제출을 지원합니다.
  • 개선 사항
    • 로그인/회원가입 접근을 인증 상태에 따라 자동 제어합니다.
    • 인증 만료 시 재발급을 시도하고, 실패 시 로그인으로 유도합니다.
    • 로그인 중복 제출 방지 및 응답 기반(필드/전체) 오류 안내를 개선했습니다.
    • 로그아웃 시 인증 정보와 관련 캐시를 정리합니다.
    • 서버/네트워크 오류에 대한 재시도 정책을 조정했습니다.

@wlsldm
wlsldm requested review from dongbi73 and yewon20804 July 26, 2026 15:19
@wlsldm wlsldm self-assigned this Jul 26, 2026
@wlsldm wlsldm added ✨ Feat 기능 개발 🧹 Chore 기타 자잘한 작업 labels Jul 26, 2026
@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tdd Ready Ready Preview, Comment Jul 27, 2026 4:40am

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@wlsldm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 54ce4723-075b-4238-b665-4a5a03b0c646

📥 Commits

Reviewing files that changed from the base of the PR and between 95436de and eeca918.

📒 Files selected for processing (2)
  • src/api/error.ts
  • src/api/queryClient.ts
📝 Walkthrough

Walkthrough

인증 토큰 저장소와 Axios API 계층, React Query 설정을 추가했습니다. 로그인·로그아웃 mutation과 토큰 재발급을 연결하고, PublicRoute·ProtectedRoute로 라우트를 분리했습니다. 도미토리 검증 API 경로와 로그인 오류 처리를 변경하고 기존 프로필 폼을 삭제했습니다.

Changes

인증 기반 및 API 연동

Layer / File(s) Summary
인증 계약과 토큰 저장소
src/types/..., src/stores/useAuthStore.ts
공통 API 응답·인증 타입과 영속화되는 access/refresh token 상태를 추가했습니다.
API와 React Query 연동
src/api/..., src/App.tsx
Axios 공개·인증 인스턴스, 토큰 재발급·401 처리, 로그인·로그아웃 mutation, 오류 처리, React Query Provider와 재시도 설정을 추가했습니다.
라우트 보호와 인증 화면 연결
src/routes/..., src/pages/login/LoginPage.tsx, src/pages/mypage/settings/SettingsPage.tsx
PublicRoute와 ProtectedRoute로 라우트를 그룹화하고 로그인·로그아웃 동작을 API mutation에 연결했습니다.
도미토리 검증 API 경로 정리
src/api/dormitory/dormVerification.ts, src/hooks/useSubmitDormVerification.ts
도미토리 검증 API 함수를 추가하고 제출 훅의 import 경로를 변경했습니다.
회원가입 프로필 폼 제거
src/pages/signup/components/ProfileForm.tsx
기존 프로필 입력 폼 컴포넌트와 관련 타입을 삭제했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: 🔧 Setting

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 직접 이슈 #49의 로그인 API 연동은 반영됐지만, 회원가입 API 연결 요구는 이 변경 내에서 확인되지 않습니다. 회원가입 API 연결 흐름과 관련 훅/페이지 연동을 추가해 이슈 #49의 두 요구사항을 모두 충족하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 로그인 API 연동이라는 핵심 변경을 간단하고 정확하게 요약합니다.
Out of Scope Changes check ✅ Passed 인증 인프라, 라우팅, 에러 처리 등은 로그인/회원가입 API 연동을 뒷받침하는 범위로 보이며 명백한 이탈 변경은 보이지 않습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/49-login-api

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/queryClient.ts`:
- Around line 5-9: Update shouldRetry to distinguish Axios HTTP statuses
explicitly: never retry Axios 4xx responses, retry Axios 5xx responses only
within the existing failure-count limit, and preserve the fallback behavior for
errors without a response status. Use isAxiosError and the extracted status as
the condition boundary.

In `@src/pages/login/LoginPage.tsx`:
- Around line 24-32: Update the onSubmit error handler to display a user-facing
fallback message when the Axios error lacks response data or its message;
otherwise preserve and show the server-provided message. Keep the change scoped
to the existing isAxiosError handling and alert call.

In `@src/stores/useAuthStore.ts`:
- Around line 12-27: Update the persist configuration in the auth store so
refreshToken is excluded from browser persistence, and keep only the access
token in memory or the existing non-persisted state as appropriate. Adjust
partialize and related token initialization or update logic around setTokens and
clearAuth to ensure refreshToken is managed through Secure, HttpOnly, SameSite
cookies rather than local browser storage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ace44baa-51f2-408e-bcb1-78012ee46cb9

📥 Commits

Reviewing files that changed from the base of the PR and between eef741f and e609e2e.

📒 Files selected for processing (16)
  • src/App.tsx
  • src/api/auth/api.ts
  • src/api/auth/query.ts
  • src/api/dormitory/dormVerification.ts
  • src/api/instance.ts
  • src/api/queryClient.ts
  • src/hooks/useSubmitDormVerification.ts
  • src/pages/login/LoginPage.tsx
  • src/pages/mypage/settings/SettingsPage.tsx
  • src/pages/signup/components/ProfileForm.tsx
  • src/routes/ProtectedRoute.tsx
  • src/routes/PublicRoute.tsx
  • src/routes/router.tsx
  • src/stores/useAuthStore.ts
  • src/types/api.ts
  • src/types/auth/auth.ts
💤 Files with no reviewable changes (1)
  • src/pages/signup/components/ProfileForm.tsx

Comment thread src/api/queryClient.ts Outdated
Comment thread src/pages/login/LoginPage.tsx Outdated
Comment on lines +12 to +27
persist(
(set) => ({
accessToken: null,
refreshToken: null,

setTokens: ({ accessToken, refreshToken }) =>
set({ accessToken, refreshToken }),
clearAuth: () => set({ accessToken: null, refreshToken: null }),
}),
{
name: "auth",
partialize: ({ accessToken, refreshToken }) => ({
accessToken,
refreshToken,
}),
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# persist 저장소 설정과 refresh token 사용 지점을 확인합니다.
rg -n -C 3 'persist\(|createJSONStorage|storage:|refreshToken' src

Repository: Leets-Official/TDD-FE

Length of output: 2497


Refresh token을 브라우저 저장소에 영구 보관하지 마세요.

storage가 없는 persist 설정은 access/refresh token을 브라우저 저장소에 보관합니다. XSS가 발생하면 토큰이 모두 탈취될 수 있으므로, refresh token은 Secure·HttpOnly·SameSite 쿠키로 관리하고 access token도 가능한 한 메모리에서만 사용하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/stores/useAuthStore.ts` around lines 12 - 27, Update the persist
configuration in the auth store so refreshToken is excluded from browser
persistence, and keep only the access token in memory or the existing
non-persisted state as appropriate. Adjust partialize and related token
initialization or update logic around setTokens and clearAuth to ensure
refreshToken is managed through Secure, HttpOnly, SameSite cookies rather than
local browser storage.

@yewon20804 yewon20804 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

완전 수고 많으셨어요 👏 API연동을 위한 세팅하느랴 고생 많으셨숩니다 ! 에러 처리를 공통으로 진행하면 좋을 것 같아서 다음과 같이 추가하면 사용처에서 경고 문구만 상황에 맞게(alert, toast..) 나타나게 하면 좋을 것 같아유 👍✨

// types/ api.ts

export interface ApiFieldError {
  field: string;
  message: string;
}

export interface ApiErrorResponse {
  success: false;
  message: string;
  data?: {
    fieldErrors?: ApiFieldError[];
  };
}
// api/ error.ts

import { isAxiosError } from "axios";

import type { ApiErrorResponse } from "@/types/api";

export const getApiErrorMessage = (error: unknown, fallback: string) => {
  if (isAxiosError<ApiErrorResponse>(error)) {
    return error.response?.data?.message ?? fallback;
  }

  return fallback;
};

이미 연동한 로그인 페이지에서는

onError: (error) => {
  alert(getApiErrorMessage(error, LOGIN_FAILED_MESSAGE));
      },

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/error.ts`:
- Around line 11-12: Update the Axios error handling in the isAxiosError branch
of src/api/error.ts so error.response?.data?.message uses fallback when it is
empty or contains only whitespace, not only when it is nullish. Preserve
non-empty server messages and the existing fallback behavior.

In `@src/api/queryClient.ts`:
- Around line 5-11: Update shouldRetry to detect Axios cancellation errors via
ERR_CANCELED or axios.isCancel(...), and return false before classifying
response-less errors as retryable. Preserve the existing retry behavior for
non-cancellation Axios errors and the failureCount < 1 limit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f48bfc97-e725-4ead-8ea3-3cde634c5ef7

📥 Commits

Reviewing files that changed from the base of the PR and between e609e2e and 95436de.

📒 Files selected for processing (5)
  • src/api/error.ts
  • src/api/queryClient.ts
  • src/constants/errorMessage.ts
  • src/pages/login/LoginPage.tsx
  • src/types/api.ts

Comment thread src/api/error.ts Outdated
Comment thread src/api/queryClient.ts
@wlsldm
wlsldm merged commit 91f4659 into dev Jul 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🧹 Chore 기타 자잘한 작업 ✨ Feat 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 로그인 api 연결

2 participants