You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ProtectedRoute页面刷新重定向问题:authState未更新时跳转至登录页

问题现象
  • 通过/login页面登录后,可正常跳转至/profile页面;但刷新/profile页面时会被重定向至/login页面
  • 认证状态(authState)通过redux-persist存储在localStorage中,checkAuth()用于验证Cookie中的JWT accessToken
问题原因与解决方案
  • 原因:页面刷新时Redux状态会重置为初始状态,redux-persist要等之后才会恢复(rehydrates)状态,这期间认证状态未恢复,导致ProtectedRoute判定用户未认证而触发重定向
  • 解决方案:将未确认的认证状态设为null,并在状态恢复期间保持loading为true,无需在ProtectedRoute中额外添加状态恢复检查,方案简洁高效

相关代码实现

src/components/ProtectedRoute.tsx

import { Navigate, useLocation } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { RootState } from '@/store/store';
import useAuthGuard from '@/hooks/useAuthGuard';

interface ProtectedRouteProps {
    children: React.ReactNode;
}

export const ProtectedRoute = ({ children }: ProtectedRouteProps): JSX.Element => {

    const { user, loading, isAuthenticated } = useSelector((state: RootState) => state.auth);
    const location = useLocation();
    console.log('Full Auth State:', { user, loading, isAuthenticated, currentPath: location.pathname });

    // 使用自定义钩子确保认证检查
    useAuthGuard();
    
    console.log(`console->log ${location.pathname}`, user);


    // 仍在加载时(比如验证token过程中),渲染加载占位
    if (loading) {
        return <div>Loading...</div>; // 替换为你项目的加载组件
    }

    // 检查用户未认证且当前不在登录页
    if (!isAuthenticated || !user) {
        // 重定向到登录页并保留目标路径
        console.log('Redirecting to login...');
        return <Navigate to="/login" state={{ from: location.pathname }} replace />;
    }
    
    return <> {children} </>;
};

src/hooks/useAuthGuard.ts

import { useSelector, useDispatch } from 'react-redux';
import { RootState, AppDispatch } from '@/store/store';
import { useEffect } from 'react';

export const useAuthGuard = () => {
    const { user, isAuthenticated, loading } = useSelector((state: RootState) => state.auth);
    const dispatch = useDispatch<AppDispatch>();
    
    useEffect(() => {
        const verifyAuth = async () => {
            try {
                 // 同时检查认证状态和用户数据
                 if (!loading && (!isAuthenticated || !user)) {
                     await dispatch(checkAuth()).unwrap();
                }
            } catch (error) {
                console.error('Auth check failed, redirecting to login');
            }
        };

        verifyAuth();
    }, [isAuthenticated, loading, dispatch]);
};

内容的提问来源于stack exchange,提问作者Shi O

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:36:04