Files
CODE_ASSISTANT/docs/troubleshootings/2026-09-11-stale-auth-refresh-401.md
T
2026-09-16 17:22:14 +09:00

2.2 KiB

저장된 로그인 정보 때문에 sessions·refresh 401 반복

증상

  • 앱을 열면 로그인 화면 대신 /api/v1/chat/sessions를 먼저 호출하고 401이 남음.
  • 이어서 /api/v1/auth/refresh가 호출되지만 refresh 쿠키가 없어 REFRESH_TOKEN_MISSING 401이 남음.

원인

authStore는 user만 localStorage에 저장하고 실제 토큰은 httpOnly 쿠키로 관리함. 그런데 ProtectedRoute가 저장된 user만 보고 보호 화면을 열었음. 쿠키가 이미 사라져도 user가 남아 있으면 SessionListPage가 먼저 마운트되어 sessions API를 호출함.

서버 진실값을 확인하려 만든 useMe()는 어디에도 마운트되지 않아 실제 로그인 검증에 쓰이지 않았음. /users/me의 refresh까지 실패하면 공통 interceptor가 요청을 세션 만료 모달 큐에 넣어 Promise를 끝내지 않으므로, 앱 시작 검증에도 그대로 쓸 수 없었음.

수정

파일 내용
2_frontend/src/shared/components/ProtectedRoute.tsx 저장된 user가 있으면 useMe() 검증이 끝날 때까지 보호 화면을 열지 않음. 검증 실패 시 user를 지우고 로그인으로 이동
2_frontend/src/features/auth/api/auth.api.ts 앱 시작 /users/me 요청에 세션 만료 큐 제외 표시 추가
2_frontend/src/lib/api/client.ts refresh 실패 시 앱 시작 검증 요청은 모달 큐에 넣지 않고 401을 호출자에게 반환
2_frontend/src/shared/components/ProtectedRoute.test.tsx 검증 중 보호 화면 차단과 실패 시 로그인 이동 회귀 검사
2_frontend/src/lib/api/client.test.ts 앱 시작 refresh 실패가 세션 만료 큐에 갇히지 않는 회귀 검사

검증

  • 회귀 검사 RED: 보호 화면이 즉시 열렸고, 초기 /users/me 요청은 세션 만료 큐에서 5초 timeout 됨.
  • 수정 후 전체 frontend 검사: 47 files, 268 tests 통과.
  • npm run build 통과.
  • 브라우저에서 stale user + 쿠키 없음으로 /snap 진입: /users/me/auth/refresh/login?from=%2Fsnap 이동, localStorage user 제거 확인. /chat/sessions 요청은 발생하지 않음.