"use client"; import { useEffect, ReactNode, useState } from "react"; import { useRouter } from "next/navigation"; import { useAuth } from "@/hooks/useAuth"; interface AuthGuardProps { children: ReactNode; requireAuth?: boolean; requireAdmin?: boolean; redirectTo?: string; fallback?: ReactNode; } /** * 인증 보호 컴포넌트 * 로그인 상태 및 권한에 따라 접근을 제어 */ export function AuthGuard({ children, requireAuth = true, requireAdmin = false, redirectTo = "/login", fallback, }: AuthGuardProps) { const { isLoggedIn, isAdmin, loading, error } = useAuth(); const router = useRouter(); const [redirectCountdown, setRedirectCountdown] = useState(null); const [authDebugInfo, setAuthDebugInfo] = useState({}); useEffect(() => { console.log("=== AuthGuard 디버깅 ==="); console.log("requireAuth:", requireAuth); console.log("requireAdmin:", requireAdmin); console.log("loading:", loading); console.log("isLoggedIn:", isLoggedIn); console.log("isAdmin:", isAdmin); console.log("error:", error); // 토큰 확인을 더 정확하게 const token = localStorage.getItem("authToken"); console.log("AuthGuard localStorage 토큰:", token ? "존재" : "없음"); console.log("현재 경로:", window.location.pathname); // 디버깅 정보 수집 setAuthDebugInfo({ requireAuth, requireAdmin, loading, isLoggedIn, isAdmin, error, hasToken: !!token, currentPath: window.location.pathname, timestamp: new Date().toISOString(), tokenLength: token ? token.length : 0, }); if (loading) { console.log("AuthGuard: 로딩 중 - 대기"); return; } // 토큰이 있는데도 인증이 안 된 경우, 잠시 대기 if (token && !isLoggedIn && !loading) { console.log("AuthGuard: 토큰은 있지만 인증이 안됨 - 잠시 대기"); return; } // 인증이 필요한데 로그인되지 않은 경우 if (requireAuth && !isLoggedIn) { console.log("AuthGuard: 인증 필요하지만 로그인되지 않음 - 5초 후 리다이렉트"); console.log("리다이렉트 대상:", redirectTo); setRedirectCountdown(5); const countdownInterval = setInterval(() => { setRedirectCountdown((prev) => { if (prev === null || prev <= 1) { clearInterval(countdownInterval); router.push(redirectTo); return null; } return prev - 1; }); }, 1000); return; } // 관리자 권한이 필요한데 관리자가 아닌 경우 if (requireAdmin && !isAdmin) { console.log("AuthGuard: 관리자 권한 필요하지만 관리자가 아님 - 5초 후 리다이렉트"); console.log("리다이렉트 대상:", redirectTo); setRedirectCountdown(5); const countdownInterval = setInterval(() => { setRedirectCountdown((prev) => { if (prev === null || prev <= 1) { clearInterval(countdownInterval); router.push(redirectTo); return null; } return prev - 1; }); }, 1000); return; } console.log("AuthGuard: 모든 인증 조건 통과 - 컴포넌트 렌더링"); }, [requireAuth, requireAdmin, loading, isLoggedIn, isAdmin, error, redirectTo, router]); // 로딩 중일 때 fallback 또는 기본 로딩 표시 if (loading) { console.log("AuthGuard: 로딩 중 - fallback 표시"); return (

AuthGuard 로딩 중...

{JSON.stringify(authDebugInfo, null, 2)}
{fallback ||
로딩 중...
}
); } // 인증 실패 시 fallback 또는 기본 메시지 표시 if (requireAuth && !isLoggedIn) { console.log("AuthGuard: 인증 실패 - fallback 표시"); return (

인증 실패

{redirectCountdown !== null && (
리다이렉트 카운트다운: {redirectCountdown}초 후 {redirectTo}로 이동
)}
{JSON.stringify(authDebugInfo, null, 2)}
{fallback ||
인증이 필요합니다.
}
); } if (requireAdmin && !isAdmin) { console.log("AuthGuard: 관리자 권한 없음 - fallback 표시"); return (

관리자 권한 없음

{redirectCountdown !== null && (
리다이렉트 카운트다운: {redirectCountdown}초 후 {redirectTo}로 이동
)}
{JSON.stringify(authDebugInfo, null, 2)}
{fallback ||
관리자 권한이 필요합니다.
}
); } console.log("AuthGuard: 인증 성공 - 자식 컴포넌트 렌더링"); return <>{children}; } /** * 로그인 여부만 확인하는 간단한 가드 */ export function RequireAuth({ children }: { children: ReactNode }) { return {children}; } /** * 관리자 권한을 요구하는 가드 */ export function RequireAdmin({ children }: { children: ReactNode }) { return ( {children} ); } export default AuthGuard;