import { useEffect } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { useAuth } from '@/contexts/AuthContext'; // 不需要登录的公共页面路径 const PUBLIC_PATHS = [ '/login', '/register', '/forgot-password', '/reset-password', '/404', '/500' ]; /** * 认证守卫Hook * 用于在组件中检查用户是否已登录 * @param requireAuth 是否需要认证,默认为true * @param redirectTo 未认证时重定向的路径,默认为'/login' */ export function useAuthGuard(requireAuth: boolean = true, redirectTo: string = '/login') { const { isAuthenticated, isLoading } = useAuth(); const navigate = useNavigate(); const location = useLocation(); // 检查当前路径是否是公共页面 const isPublicPath = PUBLIC_PATHS.some(path => location.pathname.startsWith(path) ); useEffect(() => { // 如果正在加载,不进行任何跳转 if (isLoading) { return; } // 如果需要认证但未登录且不是公共页面 if (requireAuth && !isAuthenticated && !isPublicPath) { // 保存当前URL,登录后可以重定向回来 const returnUrl = encodeURIComponent(window.location.href); navigate(`${redirectTo}?returnUrl=${returnUrl}`, { replace: true }); return; } // 如果已登录但在登录页面,重定向到首页 if (isAuthenticated && location.pathname === '/login') { navigate('/', { replace: true }); return; } }, [isAuthenticated, isLoading, location.pathname, navigate, requireAuth, redirectTo, isPublicPath]); return { isAuthenticated, isLoading, isPublicPath, // 是否应该显示内容 shouldRender: !isLoading && (isAuthenticated || isPublicPath || !requireAuth) }; } /** * 简单的认证检查Hook * 只返回认证状态,不进行自动重定向 */ export function useAuthCheck() { const { isAuthenticated, isLoading } = useAuth(); const location = useLocation(); const isPublicPath = PUBLIC_PATHS.some(path => location.pathname.startsWith(path) ); return { isAuthenticated, isLoading, isPublicPath, // 是否需要认证 requiresAuth: !isPublicPath }; }