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

如何将客户端身份验证系统迁移至新App Router并实现登录校验跳转?

在Next.js App Router中实现登录状态校验与跳转

1. 服务器组件内直接校验(推荐,安全无信息泄露)

App Router的服务器组件可以直接在服务端执行登录校验逻辑,不会将敏感逻辑暴露给前端,是最安全的方案。

受保护页面示例(如仪表盘)

app/dashboard/page.tsx

import { redirect } from 'next/navigation';
// 自行封装的获取当前用户的函数(从Cookie/数据库校验会话)
import { getCurrentUser } from '@/lib/auth';

export default async function DashboardPage() {
  const user = await getCurrentUser();

  // 未登录则重定向到登录页
  if (!user) {
    redirect('/login');
  }

  return (
    <div>
      <h1>用户仪表盘</h1>
      <p>欢迎回来,{user.nickname}</p>
    </div>
  );
}

登录页反向校验示例

app/login/page.tsx

import { redirect } from 'next/navigation';
import { getCurrentUser } from '@/lib/auth';

export default async function LoginPage() {
  const user = await getCurrentUser();

  // 已登录用户访问登录页,直接跳转到仪表盘
  if (user) {
    redirect('/dashboard');
  }

  return (
    <div>
      <h1>用户登录</h1>
      {/* 登录表单逻辑 */}
    </div>
  );
}

注:getCurrentUser需自行实现,比如从请求Cookie中读取会话ID,再去数据库校验有效性。

2. 全局中间件(Middleware)批量处理路由保护

如果多个页面都需要登录校验,用中间件可以避免重复代码,统一处理路由拦截。

创建app/middleware.ts:

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { getCurrentUser } from '@/lib/auth';

export async function middleware(request: NextRequest) {
  const user = await getCurrentUser();
  const path = request.nextUrl.pathname;

  // 定义需要登录才能访问的路由列表
  const protectedPaths = ['/dashboard', '/profile', '/settings'];
  // 定义登录/注册类路由
  const authPaths = ['/login', '/register'];

  // 未登录访问受保护路由 → 跳转登录页
  if (protectedPaths.includes(path) && !user) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // 已登录访问登录/注册路由 → 跳转仪表盘
  if (authPaths.includes(path) && user) {
    return NextResponse.redirect(new URL('/dashboard', request.url));
  }

  // 其他情况正常放行
  return NextResponse.next();
}

// 指定中间件生效的路由范围
export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*', '/settings/:path*', '/login', '/register'],
};

注:中间件运行在Edge Runtime,getCurrentUser需避免使用Node.js专属API,比如用request.cookies.get()读取会话Cookie。

3. 客户端组件内校验(适配动态交互场景)

如果是带交互逻辑的客户端组件(需加'use client'指令),可以用useRouter实现跳转:

'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
// 自定义Hook,用于在客户端获取用户状态(可结合SWR/React Query实现)
import { useUser } from '@/hooks/useUser';

export default function ClientProtectedSection() {
  const { user, loading } = useUser();
  const router = useRouter();

  useEffect(() => {
    // 加载完成后判断用户状态,未登录则跳转
    if (!loading && !user) {
      router.push('/login');
    }
  }, [user, loading, router]);

  // 加载状态下显示占位符,避免页面闪屏
  if (loading) {
    return <div>加载中...</div>;
  }

  return (
    <div>
      <p>仅登录用户可见的动态内容</p>
    </div>
  );
}

关键注意事项

  • 优先使用服务器端校验/中间件,避免前端先渲染敏感内容再跳转的闪屏问题
  • 中间件适合全局路由规则,服务器组件适合单页定制化校验
  • 客户端校验仅用于动态交互场景,需妥善处理加载状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:38:09