-
Notifications
You must be signed in to change notification settings - Fork 0
Description
📝 현재 문제점
- 프론트엔드(Next.js)에서 로그아웃 동작이 미구현되어 있어, 사용자가 세션을 종료할 방법이 없습니다.
- 백엔드에는
/api/admin/logout엔드포인트가 이미 구현되어 있으며, 쿠키 기반 토큰(accessToken, refreshToken, authStatus)을 만료 처리합니다. - 현 상태에서는 브라우저 쿠키/클라이언트 상태가 남아 있을 수 있어, 보안 및 사용자 경험 측면에서 문제가 발생합니다.
🛠️ 해결 방안 / 제안 기능
-
Next.js(App Router)에서 로그아웃 액션/유틸 함수를 구현하여
/api/admin/logout에POST요청을 전송합니다.- 서버 구현에 맞춰
consumes = multipart/form-data이므로 빈FormData를 body로 전송합니다. - 쿠키 전송을 위해
credentials: 'include'옵션을 반드시 사용합니다. (서버는 응답으로 쿠키 삭제를 수행)
- 서버 구현에 맞춰
-
요청 성공/실패와 무관하게 클라이언트 측 인증 상태를 정리합니다.
- 전역 상태(있다면) 및
localStorage/sessionStorage에 저장된 인증 관련 값 초기화 - 인증 관련 캐시(SWR/React Query 등 사용 시) 무효화
- 전역 상태(있다면) 및
-
후속 동작
- 인증이 필요한 페이지에서 로그인 페이지로 리다이렉트 (
router.replace('/login')) - 레이아웃/헤더의 “로그아웃” 버튼에 위 동작 연결
- 인증이 필요한 페이지에서 로그인 페이지로 리다이렉트 (
-
예시 코드 (동일 오리진 기준)
'use client'; import { useRouter } from 'next/navigation'; export function LogoutButton() { const router = useRouter(); const onLogout = async () => { try { const form = new FormData(); // 서버가 multipart/form-data 기대 await fetch('/api/admin/logout', { method: 'POST', body: form, credentials: 'include', }); } catch (e) { // 로깅 정도만 수행 console.error(e); } finally { // 클라이언트 상태 정리 try { localStorage.clear(); } catch {} try { sessionStorage.clear(); } catch {} router.replace('/login'); // 실제 경로 확인 필요 router.refresh(); } }; return ( <button onClick={onLogout}> 로그아웃 </button> ); }
🙋♂️ 담당자
- 백엔드: 이름
- 프론트엔드: @Chuseok22
- 디자인: 이름
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
작업 완료작업 완료 상태인 경우 (이슈 폐쇄)작업 완료 상태인 경우 (이슈 폐쇄)