You need to enable JavaScript to run this app. Firebase+React无密码认证完成后PrivateRoute仍跳转登录页问题
优惠活动
大模型
产品
解决方案
定价
更多

Firebase+React无密码认证完成后PrivateRoute仍跳转登录页问题

问题原因&解决方案

1. 认证初始化异步导致路由提前跳转

Firebase的持久化登录状态恢复是异步操作,你当前AuthProvider初始化时isAuth默认设为false,在onAuthStateChanged回调触发、拿到真实登录状态前,PrivateRoute已经判定未登录,直接触发重定向回到登录页。
修改useAuthContext.js,新增加载状态避免提前跳转:

export const AuthDataContext = createContext(null);

const AuthProvider = (props) => {
    const [isAuth, setIsAuth] = useState(false);
    // 新增认证状态加载标识
    const [authLoading, setAuthLoading] = useState(true);

    useEffect(() => {
        const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
            setIsAuth(!!user);
            // 状态确认后关闭加载
            setAuthLoading(false);
        });
        // 组件卸载时取消订阅防止内存泄漏
        return () => unsubscribe();
    }, []);

    const onLogin = () => setIsAuth(true);

    const onLogout = () => {
        firebase.auth().signOut();
        setIsAuth(false);
    };

    // 把加载状态同步到上下文
    return <AuthDataContext.Provider value={{ isAuth, authLoading, onLogin, onLogout }} {...props} />;
};

export default AuthProvider;
export const useAuthDataContext = () => useContext(AuthDataContext);

修改PrivateRoute.js,加载状态下不做跳转判定:

const PrivateRoute = ({ component: Component, ...rest }) => {
    const { isAuth, authLoading } = useAuthDataContext();

    console.log("isAuth", isAuth);
    return <Route {...rest} component={(props) => {
        if (authLoading) return <div>认证状态加载中...</div>;
        return isAuth ? <Component {...props} /> : <Redirect to="/" />;
    }} />;
};

2. 登录成功后缺少路由跳转逻辑

你当前登录完成后仍然停留在登录页,需要补充登录后的跳转逻辑。修改LoginPage.js:
首先引入路由跳转hook:

import { useHistory } from 'react-router-dom';

在LoginPage组件内获取history实例:

const LoginPage = () => {
    const history = useHistory();
    // 原有代码不变

修改两处登录成功后的回调,添加跳转:
第一处useEffect内的登录逻辑:

firebase
    .auth()
    .signInWithEmailLink(savedEmail, window.location.href)
    .then(() => {
        window.localStorage.removeItem("emailForSignIn");
    })
    .then(onLogin)
    .then(() => history.push('/dashboard')) // 新增跳转
    .catch((error) => {
        console.log(error);
        setMessage(error);
    });

第二处onSubmit内的登录逻辑:

firebase
    .auth()
    .signInWithEmailLink(email, window.location.href)
    .then(() => {
        window.localStorage.removeItem("emailForSignIn");
    })
    .then(onLogin)
    .then(() => history.push('/dashboard')) // 新增跳转
    .catch((error) => {
        console.log(error);
    });

额外检查项

确认Firebase控制台中,已将localhost加入授权域名列表,且邮箱链接认证功能开关已开启。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 04:45:06