import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { useAuthStore } from '@/stores'; import { authApi } from '@/api'; /** * 어드민 인증 훅 * 토큰 유효성 검증 및 미인증 시 리다이렉트 * @param {object} options - 옵션 * @param {string} options.redirectTo - 미인증 시 리다이렉트 경로 (기본: /admin) * @param {boolean} options.required - 인증 필수 여부 (기본: true) */ export function useAdminAuth(options = {}) { const { redirectTo = '/admin', required = true } = options; const navigate = useNavigate(); const { token, user, logout, isAuthenticated } = useAuthStore(); // 토큰 검증 쿼리 const { data, isLoading, isError } = useQuery({ queryKey: ['admin', 'auth'], queryFn: authApi.verifyToken, enabled: !!token, retry: false, staleTime: 1000 * 60 * 5, // 5분 캐시 }); // 토큰 없거나 검증 실패 시 처리 // 리다이렉트는 DOM 조작이므로 useEffect 사용 허용 useEffect(() => { if (required && (!token || isError)) { logout(); navigate(redirectTo); } }, [token, isError, required, logout, navigate, redirectTo]); return { user: data?.user || user, isLoading: !token ? false : isLoading, isAuthenticated: !!data?.valid || isAuthenticated, isError, }; } /** * 로그인 페이지에서 사용하는 훅 * 이미 인증된 경우 리다이렉트 * @param {string} redirectTo - 인증된 경우 리다이렉트 경로 */ export function useRedirectIfAuthenticated(redirectTo = '/admin/dashboard') { const navigate = useNavigate(); const { isAuthenticated, token } = useAuthStore(); // 토큰 검증 const { data, isLoading } = useQuery({ queryKey: ['admin', 'auth'], queryFn: authApi.verifyToken, enabled: !!token, retry: false, }); useEffect(() => { if (data?.valid) { navigate(redirectTo); } }, [data, navigate, redirectTo]); return { isLoading: !!token && isLoading, isAuthenticated: !!data?.valid, }; }