-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
feat: 자동 로그인(Auto-Login) 구현
배경 및 문제점
현재 앱은 OAuth 로그인 후 accessToken과 refreshToken을 쿠키에 저장하지만, 실제로 refreshToken을 활용하는 로직이 전혀 없습니다. 이로 인해 아래와 같은 문제가 발생합니다.
- 브라우저 새로고침 또는 탭 재방문 시:
accessToken쿠키가 만료되면 바로 로그인 페이지로 리다이렉트됨 - 모바일 앱 재실행 시: WebView 쿠키가 유지되지 않아 매번 소셜 로그인 재요구
- 401 에러 발생 시: 자동 갱신 없이 단순 에러 throw → UX 단절
목표
앱 재진입 시 사용자가 소셜 로그인 버튼을 다시 클릭하지 않아도 자동으로 인증 상태가 복원된다.
accessToken유효 → 자동 로그인accessToken만료 +refreshToken유효 → 무음 갱신(Silent Refresh) 후 자동 로그인refreshToken까지 만료 → 로그인 페이지 이동
구현 범위
신규 파일 (2개)
apps/web/src/lib/auth-event.ts
- Axios 인터셉터(React 컨텍스트 외부)에서 React Router 네비게이션을 이벤트로 연결하는 브릿지
apps/web/src/api/token.ts
refreshAccessToken():POST /api/auth/reissue-token호출- 헤더:
Refresh: {refreshToken} - 바디:
{ member_id: number } - Promise 공유 패턴으로 동시 다발 호출 시 API 1회만 발생
- 헤더:
clearAuthCookies(): 인증 쿠키 일괄 제거 유틸
수정 파일 (8개)
| 파일 | 변경 내용 |
|---|---|
apps/web/src/api/index.ts |
onErrorResponse async화, 401을 switch 이전에 가로채어 토큰 갱신 후 원래 요청 재시도 |
apps/web/src/layout/RequireLoginLayout.tsx |
refreshToken 기반 복원 로직, 갱신 중 로딩 UI, auth-event 리스너 등록 |
apps/web/src/config/storage-keys.ts |
COOKIE_KEYS.accessToken, refreshToken, memberId 상수 추가 |
apps/web/src/hooks/api/login/usePostSignOut.ts |
로그아웃 API 실패 시에도 로컬 쿠키/상태 정리 |
apps/web/src/hooks/api/login/usePostSignIn.ts |
쿠키 키 상수 사용 |
apps/web/src/hooks/api/login/usePostSignUp.ts |
쿠키 키 상수 사용 |
apps/web/src/hooks/api/login/usePostAppleToken.ts |
쿠키 키 상수 사용 |
apps/web/src/hooks/api/user/useDeleteUser.ts |
중복 Authorization 헤더 제거 (인터셉터에 위임) |
apps/mobile/layout/webview-layout/index.tsx |
sharedCookiesEnabled, thirdPartyCookiesEnabled 추가 |
기술적 설계 포인트
401 자동 갱신 인터셉터
API 호출 → 401 응답
↓
이미 재시도한 요청? (WeakSet 확인)
YES → clearAuthCookies() + 로그인 이동
NO → refreshAccessToken() 호출
↓ 성공: 새 토큰으로 원래 요청 재시도
↓ 실패: clearAuthCookies() + 로그인 이동
동시 다발 401 처리
refreshPromise싱글턴으로 토큰 갱신 API는 항상 1회만 호출- 갱신 실패 직후 2초 쿨다운으로 불필요한 재시도 방지
RequireLoginLayout 복원 흐름
마운트
↓
isLogin=true + accessToken 쿠키 있음? → 즉시 통과
isLogin=true + accessToken 없음? → refreshToken으로 갱신 시도
isLogin=false + accessToken 있음? → /member-info로 사용자 정보 복원
accessToken 없음 + refreshToken 있음? → 갱신 후 사용자 정보 복원
둘 다 없음? → /login 이동
↓
갱신 중: LoadingModal 표시 (빈 화면 깜빡임 방지)
엣지 케이스
| 시나리오 | 동작 |
|---|---|
| 동시 다발 401 | 갱신 1회만 발생, 이후 요청은 새 토큰으로 재시도 |
| refreshToken 만료 | 로그인 페이지 이동, 현재 경로 prev-path 쿠키 저장 |
| 로그아웃 API 실패 | 로컬 쿠키/상태 강제 정리 후 로그인 이동 |
| 모바일 앱 강제 종료 후 재실행 | sharedCookiesEnabled로 쿠키 유지 → 자동 복원 |
isLogin=true + 쿠키 없음 (상태 불일치) |
refreshToken 확인 후 갱신 또는 로그인 이동 |
참고
- 활용 API:
POST /api/auth/reissue-token(헤더:Refresh, 바디:{ member_id }) - 응답에 전체 사용자 정보 포함 → 갱신 후 별도
/member-info호출 불필요
체크리스트
- 브라우저 재방문 시 accessToken 유효하면 자동 로그인
- accessToken 만료 시 refreshToken으로 무음 갱신
- refreshToken 만료 시 로그인 페이지 이동
- 갱신 중 LoadingModal 표시
- 동시 다발 401에서 갱신 API 1회만 호출
- 로그아웃 후 자동 로그인 안 됨
- iOS 앱 재실행 후 로그인 유지
- Android 앱 재실행 후 로그인 유지
- TypeScript 빌드 에러 없음
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels