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

如何使用React+Next.js防止未登录用户访问内部页面

Next.js 实现未登录用户自动重定向到登录页

基于你当前用sessionStorage存储登录状态的逻辑,下面分两种主流路由方案给出实现方式:

一、Pages Router(传统路由)

方法:封装鉴权高阶组件(HOC)

创建一个通用的鉴权组件,所有需要登录才能访问的页面都用它包裹:

// components/RequireAuth.tsx
import { useEffect } from 'react';
import { useRouter } from 'next/router';

const RequireAuth = ({ children }: { children: React.ReactNode }) => {
  const router = useRouter();

  useEffect(() => {
    // 检查sessionStorage中的登录标识
    const email = sessionStorage.getItem('email');
    if (!email) {
      // 未登录则重定向到登录页
      router.push('/index/login');
    }
  }, [router]);

  return children;
};

export default RequireAuth;

在需要保护的页面(比如pages/dashboard.tsx)中使用:

// pages/dashboard.tsx
import RequireAuth from '../components/RequireAuth';

const Dashboard = () => {
  return <div>仪表盘页面</div>;
};

export default RequireAuth(Dashboard);

补充:服务端鉴权(可选)

如果你的登录状态存在服务端会话(比如Cookie),可以在页面的getServerSideProps中验证,避免客户端渲染时的页面闪烁:

// pages/dashboard.tsx
export async function getServerSideProps(context: any) {
  const { req } = context;
  // 从Cookie中读取登录状态(根据实际存储方式调整)
  const email = req.cookies.email;

  if (!email) {
    return {
      redirect: {
        destination: '/index/login',
        permanent: false,
      },
    };
  }

  return { props: {} };
}

二、App Router(App目录路由)

方法1:客户端组件鉴权布局

创建一个客户端组件作为鉴权布局,将所有需要保护的页面放在同一个目录下并使用该布局:

// app/(protected)/layout.tsx
'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function ProtectedLayout({ children }: { children: React.ReactNode }) {
  const router = useRouter();

  useEffect(() => {
    const email = sessionStorage.getItem('email');
    if (!email) {
      router.push('/index/login');
    }
  }, [router]);

  return <>{children}</>;
}

把所有内部页面(比如dashboard、profile)放在app/(protected)目录下,访问这些页面时会自动触发鉴权逻辑。

方法2:Middleware中间件(适合服务端会话)

如果登录状态存储在服务端(比如Cookie),可以用Middleware做全局鉴权,拦截未登录请求:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // 排除登录页和静态资源路径
  if (request.nextUrl.pathname.startsWith('/index/login') || request.nextUrl.pathname.startsWith('/_next')) {
    return NextResponse.next();
  }

  // 从Cookie中读取登录状态
  const email = request.cookies.get('email')?.value;

  if (!email) {
    // 未登录则重定向到登录页
    return NextResponse.redirect(new URL('/index/login', request.url));
  }
}

// 指定需要鉴权的路由规则
export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*'], // 替换为你的内部页面路由
};

登出逻辑补充

记得在登出时清除sessionStorage中的登录状态:

const handleLogout = () => {
  sessionStorage.removeItem('email');
  router.push('/index/login');
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:15:37