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

Next.js 13如何实现路由保护?解决req.page缺失及闪屏问题

Next.js 13 路由保护方案(适配动态路由场景)

方案1:使用中间件(Middleware)全局拦截

Next.js 13 App Router 官方推荐用中间件实现路由保护,它能在页面渲染前执行逻辑,完美处理 /user/[id] 这类动态路由,还能彻底避免内容闪屏。

  • 实现步骤:
    1. 在项目根目录创建 middleware.ts(或 .js)文件
    2. 借助 NextRequest 和 NextResponse 检测认证状态、匹配目标路由
    3. 示例代码:
      import { NextRequest, NextResponse } from 'next/server';
      
      export function middleware(request: NextRequest) {
        // 从Cookie/Session等获取真实认证状态,这里仅做示例
        const isAuthenticated = request.cookies.get('auth-token')?.value;
      
        // 定义需要保护的路由,支持动态路由通配符
        const protectedRoutes = ['/about', '/user', '/user/:id*'];
      
        // 校验当前请求是否命中保护路由
        const matchesProtectedRoute = protectedRoutes.some(route => {
          const routeRegex = new RegExp(`^${route.replace(':id*', '.*')}$`);
          return routeRegex.test(request.nextUrl.pathname);
        });
      
        if (matchesProtectedRoute && !isAuthenticated) {
          // 未认证则重定向至登录页,替换为你的实际登录路由
          return NextResponse.redirect(new URL('/login', request.url));
        }
      
        // 认证通过或路由无需保护,继续处理请求
        return NextResponse.next();
      }
      
      // 指定中间件生效的路由范围,可进一步缩小拦截范围
      export const config = {
        matcher: ['/about', '/user/:path*'],
      };
      

方案2:Server Components 页面内直接校验

如果使用App Router的Server Components,可在页面组件中直接做认证检查并触发重定向——Server Components在服务器端渲染,不会在客户端暴露未授权内容,自然不会有闪屏问题。

  • 示例(/user/[id]/page.tsx):
    import { redirect } from 'next/navigation';
    // 假设用NextAuth处理认证,可替换为自定义的认证逻辑
    import { getServerSession } from 'next-auth/next';
    import { authOptions } from '@/app/api/auth/[...nextauth]/route';
    
    export default async function UserProfilePage({ params }: { params: { id: string } }) {
      const session = await getServerSession(authOptions);
    
      if (!session) {
        redirect('/login');
      }
    
      // 这里可通过params.id获取动态路由的slug,正常处理页面逻辑
      return <div>用户ID:{params.id} 的个人页面</div>;
    }
    

方案3:Client Components 避免闪屏的处理方式

如果必须使用Client Components,要避免闪屏,需先完成认证状态校验,再渲染页面核心内容:

  • 示例:
    'use client';
    
    import { useEffect, useState } from 'react';
    import { useRouter } from 'next/navigation';
    import { getSession } from 'next-auth/react';
    
    export default function UserProfilePage({ params }: { params: { id: string } }) {
      const router = useRouter();
      const [isLoading, setIsLoading] = useState(true);
    
      useEffect(() => {
        const checkAuthStatus = async () => {
          const session = await getSession();
          if (!session) {
            router.push('/login');
          }
          setIsLoading(false);
        };
        checkAuthStatus();
      }, [router]);
    
      // 认证校验完成前,仅显示加载态(如骨架屏),不渲染页面内容
      if (isLoading) {
        return <div>加载中...</div>;
      }
    
      return <div>用户ID:{params.id} 的个人页面</div>;
    }
    

关于next-shield闪屏的原因

next-shield是在客户端层面做路由守卫,会先渲染页面内容,再触发认证检查和重定向,因此会出现短暂的内容闪屏。而上述中间件、Server Components方案都是在服务器端提前处理逻辑,从根源上避免了这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:15:48