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

Next.js 13中如何检测404页面?解决未登录用户访问限制问题

在Next.js 13中检测404页面并调整Firebase认证重定向逻辑

你当前的Firebase认证重定向逻辑会强制未登录用户跳转到登录页,导致他们无法访问404页面。可以通过以下两种方式实现404页面检测,调整重定向规则:

方法一:利用React Context标记404状态(推荐,支持所有404场景)

这种方式能覆盖静态、动态路由导致的所有404情况,通过Context在not-found.tsx中标记当前页面状态,再在认证逻辑中读取该状态跳过重定向。

  1. 创建NotFound状态Context
// app/auth-context.tsx
'use client';
import { createContext, useContext, useState, ReactNode } from 'react';

const NotFoundContext = createContext<{ isNotFound: boolean; setIsNotFound: (value: boolean) => void }>({
  isNotFound: false,
  setIsNotFound: () => {},
});

export function NotFoundProvider({ children }: { children: ReactNode }) {
  const [isNotFound, setIsNotFound] = useState(false);
  return (
    <NotFoundContext.Provider value={{ isNotFound, setIsNotFound }}>
      {children}
    </NotFoundContext.Provider>
  );
}

export function useNotFound() {
  return useContext(NotFoundContext);
}
  1. 在根布局中挂载Provider
// app/layout.tsx
import { NotFoundProvider } from './auth-context';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="zh-CN">
      <body>
        <NotFoundProvider>{children}</NotFoundProvider>
      </body>
    </html>
  );
}
  1. 在not-found.tsx中设置404状态
// app/not-found.tsx
'use client';
import { useNotFound } from './auth-context';
import { useEffect } from 'react';

export default function NotFound() {
  const { setIsNotFound } = useNotFound();

  useEffect(() => {
    setIsNotFound(true);
    // 页面卸载时重置状态
    return () => setIsNotFound(false);
  }, [setIsNotFound]);

  return (
    <div>
      <h1>404 - 页面不存在</h1>
    </div>
  );
}
  1. 修改认证重定向逻辑
'use client';
import { useRouter, usePathname } from 'next/navigation';
import { useNotFound } from './auth-context';
import { auth } from './firebase-config';
import { onAuthStateChanged } from 'firebase/auth';
import { useEffect } from 'react';

export default function AuthRedirect() {
  const router = useRouter();
  const path = usePathname();
  const { isNotFound } = useNotFound();

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      if (user) {
        // 已登录时,若在登录页则跳转首页
        if (path === "/login") {
          router.push("/");
        }
      } else {
        // 未登录时,仅当不是登录页且不是404页时才跳转登录页
        if (path !== "/login" && !isNotFound) {
          router.push("/login");
        }
      }
    });

    return unsubscribe;
  }, [path, router, isNotFound]);

  return null;
}

方法二:直接匹配404路径(仅适用于静态404页面)

如果你的404页面是固定的/404路径,可以直接在逻辑中判断路径是否为404,但这种方法无法覆盖动态路由导致的404场景:

onAuthStateChanged(auth, (user) => {
  if (user) {
    if (path === "/login") {
      router.push("/");
    }
  } else {
    // 排除登录页和404路径
    if (path !== "/login" && path !== "/404") {
      router.push("/login");
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:13:09