73 lines
2.1 KiB
JavaScript
73 lines
2.1 KiB
JavaScript
|
|
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,
|
||
|
|
};
|
||
|
|
}
|