-
Notifications
You must be signed in to change notification settings - Fork 3
Fix: 불필요한 401 방지 #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: 불필요한 401 방지 #559
Conversation
|
Caution Review failedThe pull request is closed. WalkthroughAuthInitializer와 useUser 훅이 Zustand 스토어의 Changes
Sequence Diagram(s)sequenceDiagram
actor User as 사용자
participant App as App
participant AuthInit as AuthInitializer
participant Store as Zustand Store
participant RQ as React Query
participant API as Auth API
User->>App: 앱 로드
App->>AuthInit: 마운트
AuthInit->>Store: user 조회
alt user 존재
AuthInit->>RQ: refetch() (세션 검증)
RQ->>API: GET /session (또는 유사 엔드포인트)
alt 성공
RQ->>Store: setUser(서버 응답)
else 실패
RQ->>Store: clearUser()
end
else user 없음
Note over AuthInit,RQ: 네트워크 요청 수행 안 함
end
sequenceDiagram
participant Component as 임의 컴포넌트
participant useUser as useUser 훅
participant Store as Zustand Store
participant RQ as React Query
participant API as Auth API
Component->>useUser: 호출
useUser->>Store: user 조회
alt enabled: !!user
useUser->>RQ: useQuery(enabled=true)
RQ->>API: 사용자 데이터 조회
alt 성공
RQ->>Store: setUser()
else 실패
RQ->>Store: clearUser()
end
else enabled=false
Note over useUser: 쿼리 비활성화 (대기)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (2)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
✅ Preview Deployment Ready!🔗 Preview URL: https://roam-ready-3iveqb2kh-yongmins-projects-bf5f7733.vercel.app This preview will be automatically updated on new commits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/domain/Auth/hooks/useUser.ts (2)
74-79: 모든 에러에서 clearUser() 호출 → 오프라인/서버 오류에도 강제 로그아웃 위험.에러가 401/403일 때만 사용자 상태를 비우도록 제한하세요.
useEffect(() => { // isError가 true가 되면 (데이터 로딩 실패 시) if (queryResult.isError) { - clearUser(); + const status = + (queryResult.error as any)?.response?.status ?? + (queryResult.error as any)?.status; + if (status === 401 || status === 403) { + clearUser(); + } } }, [queryResult.isError, clearUser]);
57-64: retry 정책 보완 및 staleTime 옵션 추가 필요
enabled: !!user설정은 AuthInitializer의 수동refetch로직으로 초기 인증 검증이 수행되므로 그대로 유지하세요.- 기본
retry: 1은 401/403을 포함한 모든 오류에 재시도를 수행하므로, 401·403 및 기타 4xx 에러를 차단하고 네트워크/5xx만 1회 재시도하도록 함수 형태로 변경해야 합니다.- JSDoc에 명시된 5분(
staleTime) 옵션이 코드에 누락되어 있으므로staleTime: 5 * 60 * 1000을 추가하세요.queryKey: ['user', 'me'], queryFn: getMe, - enabled: !!user, - retry: 1, + enabled: !!user, + staleTime: 5 * 60 * 1000, + retry: (failureCount, error) => { + const status = + (error as any)?.response?.status ?? (error as any)?.status; + // 인증 에러 및 4xx는 재시도하지 않음 + if (status === 401 || status === 403 || (status && status < 500)) return false; + // 네트워크/5xx만 1회 재시도 + return failureCount < 1; + }, refetchOnWindowFocus: true, refetchOnReconnect: true,
🧹 Nitpick comments (3)
src/domain/Auth/hooks/useUser.ts (3)
66-73: onSuccess/onError로 부가 작업을 옮기면 의존성/재렌더 줄어듭니다.효과를 훅 옵션으로 수렴해 사이드이펙트 흐름을 한 곳에서 관리하세요.
const queryResult = useQuery({ queryKey: ['user', 'me'], queryFn: getMe, enabled: !!user, staleTime: 5 * 60 * 1000, retry: (failureCount, error) => { /* 위와 동일 */ }, onSuccess: setUser, onError: (error) => { const s = (error as any)?.response?.status ?? (error as any)?.status; if (s === 401 || s === 403) clearUser(); }, });
55-55: 스토어 구독 수 최소화(미세 최적화).동일 스토어를 3번 구독 중입니다. 한 번의 셀렉터 + shallow 비교로 묶으면 리렌더를 줄일 수 있습니다.
import { shallow } from 'zustand/shallow'; const { user, setUser, clearUser } = useRoamReadyStore( (s) => ({ user: s.user, setUser: s.setUser, clearUser: s.clearUser }), shallow, );
20-30: 문서-코드 불일치: staleTime 5분 설명 있으나 코드에 없음.옵션을 추가(위 Diff 참조)하거나 주석을 수정하세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/app/_components/AuthInitializer.tsx(2 hunks)src/domain/Auth/hooks/useUser.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/app/_components/AuthInitializer.tsx (1)
src/shared/store/index.ts (1)
useRoamReadyStore(32-47)
src/domain/Auth/hooks/useUser.ts (2)
src/shared/store/index.ts (1)
useRoamReadyStore(32-47)src/domain/Auth/services/index.ts (1)
getMe(85-87)
⏰ 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: vercel-preview
| // 스토어에 사용자 정보가 있을 경우 (즉, 이전에 로그인했을 경우)에만 | ||
| // 세션 유효성 검사를 위해 refetch를 실행합니다. | ||
| if (user) { | ||
| refetch(); | ||
| } | ||
| }, [refetch, user]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
user 의존 refetch는 중복 호출·루프 위험 → 제거 권장.
- useUser 내부에서 enabled: !!user로 이미 자동 fetch가 발생합니다.
- useUser 성공 시 setUser가 호출되면 user 레퍼런스가 바뀌고, 본 useEffect가 다시 refetch를 불러 무한/과도한 요청으로 이어질 수 있습니다(중복 fetch 또는 fetch-→setUser→refetch 반복).
불필요한 refetch와 store 의존을 제거해 Initializer를 “훅 마운트만” 하도록 단순화하세요.
-'use client';
-
-import { useEffect } from 'react';
+'use client';
import { useUser } from '@/domain/Auth/hooks/useUser';
-import { useRoamReadyStore } from '@/shared/store';
export default function AuthInitializer() {
- const { refetch } = useUser(); // 쿼리 객체를 받아서
- const user = useRoamReadyStore((state) => state.user);
-
- useEffect(() => {
- // 스토어에 사용자 정보가 있을 경우 (즉, 이전에 로그인했을 경우)에만
- // 세션 유효성 검사를 위해 refetch를 실행합니다.
- if (user) {
- refetch();
- }
- }, [refetch, user]);
+ // enabled: !!user 로 이미 내부에서 자동 실행됨
+ useUser();
return null;
}대안(정 꼭 필요하다면): status/isFetching을 함께 받아 “idle이고 user가 생겼을 때 1회만” refetch 하도록 강하게 가드하세요.
const { refetch, status, isFetching } = useUser();
useEffect(() => {
if (user && status === 'idle' && !isFetching) refetch();
}, [refetch, user, status, isFetching]);Also applies to: 17-17, 6-6, 3-3
🤖 Prompt for AI Agents
In src/app/_components/AuthInitializer.tsx around lines 20 to 25, the useEffect
that calls refetch when user exists causes redundant/looping fetches because
useUser already auto-fetches with enabled: !!user and setUser changes user
reference; remove the user-dependent refetch to make the initializer only mount
the hook (delete the if (user) refetch() call and remove user from the effect
deps so effect runs only on mount/refetch identity), or if you must keep a
guarded refetch implement a one-time guard by also reading status/isFetching
from useUser and only calling refetch when user exists AND status === 'idle' AND
!isFetching so it runs once.
9310db4 to
36be57d
Compare
✅ Preview Deployment Ready!🔗 Preview URL: https://roam-ready-a431w5x5z-yongmins-projects-bf5f7733.vercel.app This preview will be automatically updated on new commits. |
👻 관련 이슈 번호
👻 요약
👻 주요 변경 사항
처음 웹사이트에 진입하거나 로그아웃하면 401에러가 개발자 도구 콘솔에 찍힌다.
사용자 입장에서는 보이지 않으니 심각한 문제는 아니지만 콘솔 노이즈을 줄이고 불필요한 API를 호출하지 않도록 수정
👻 체크리스트
📷 UI 변경 사항
👻 문제 사항
👻 논의 사항
👻 기타 참고 사항
Summary by CodeRabbit