0Pricing
React Academy · 课时

基于中间件的路由保护

使用 Next.js 中间件和身份验证回调,在边缘将未验证身份的用户重定向。

基于中间件的路由保护 是 CoddyKit 上的免费 React Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

什么是 Next.js 中间件

中间件会在请求到达路由之前于边缘运行环境中执行。它可以重定向请求、重写请求或添加标头,非常适合在不加载服务器组件的情况下执行身份验证检查。

创建中间件

在项目根目录创建 middleware.ts。导出一个 middleware 函数和一个 config 匹配器。

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

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth-token')?.value;
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*'],
};

匹配器模式

matcher 数组使用路径模式。对于任意子路径,请使用 :path*;也可以使用负向前瞻排除路径。

export const config = {
  matcher: [
    // Protect all routes except public ones:
    '/((?!login|register|_next|api/auth|favicon.ico).*)',
  ],
};

Auth.js 中间件集成

Auth.js(v5)提供了开箱即用的中间件导出项。请在 middleware.ts 中结合匹配器重新导出它。

// middleware.ts
export { auth as middleware } from '@/auth';

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*'],
};

在中间件中检查 JWT

请使用 jose 库在中间件中验证 JWT 令牌(兼容边缘运行环境 — 无需 Node.js 的加密模块)。

import { jwtVerify } from 'jose';

export async function middleware(request: NextRequest) {
  const token = request.cookies.get('token')?.value;
  if (!token) return NextResponse.redirect(new URL('/login', request.url));
  try {
    await jwtVerify(token, new TextEncoder().encode(process.env.JWT_SECRET));
    return NextResponse.next();
  } catch {
    return NextResponse.redirect(new URL('/login', request.url));
  }
}

基于角色的中间件

从令牌中读取用户角色;如果角色权限不足,则将用户重定向到未授权页面。

const { payload } = await jwtVerify(token, secret);
if (request.nextUrl.pathname.startsWith('/admin') && payload.role !== 'admin') {
  return NextResponse.redirect(new URL('/unauthorized', request.url));
}

向路由处理程序传递数据

在中间件中设置请求标头,将解码后的用户数据传递给服务器组件,从而无需重新获取令牌。

const response = NextResponse.next();
response.headers.set('x-user-id', payload.sub as string);
response.headers.set('x-user-role', payload.role as string);
return response;

// In a Server Component:
import { headers } from 'next/headers';
const userId = headers().get('x-user-id');

在中间件中重写 URL

使用 NextResponse.rewrite() 为某个 URL 提供不同的页面,同时不改变浏览器的地址栏 — 这对 A/B 测试或功能开关很有用。

const isInExperiment = Math.random() > 0.5;
if (isInExperiment) {
  return NextResponse.rewrite(new URL('/home-v2', request.url));
}

中间件中的地理位置和 IP

从 NextRequest 对象中获取请求的地理数据和 IP,以执行基于地区的重定向或拦截。

const country = request.geo?.country ?? 'US';
if (country === 'XX') {
  return NextResponse.redirect(new URL('/region-blocked', request.url));
}

中间件性能

中间件会在边缘运行环境中处理每个匹配的请求。请保持中间件轻量 — 避免执行繁重的计算或导入大型模块,并且只能使用兼容边缘运行环境的库。

组合身份验证路由和公开路由

一种常见模式是:除了特定的公开路径允许列表之外,保护所有路径,并在身份验证逻辑之前检查该列表。

const PUBLIC_PATHS = ['/login', '/register', '/about'];
const isPublic = PUBLIC_PATHS.some(p => request.nextUrl.pathname.startsWith(p));
if (isPublic) return NextResponse.next();

// Auth check for non-public routes
const token = request.cookies.get('token')?.value;
if (!token) return NextResponse.redirect(new URL('/login', request.url));

快速检查

在 Next.js 中间件内验证 JWT 时,应使用哪个库,而不是 Node.js 的加密模块?

回顾

在项目根目录创建 middleware.ts,并配置 matcher。使用兼容边缘运行环境的 jose 检查身份验证令牌,重定向未通过身份验证的用户,并通过响应标头将解码后的数据传递给服务器组件。保持中间件快速且依赖精简。

常见问题解答

「基于中间件的路由保护」课时是免费的吗?

是的 — 「基于中间件的路由保护」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「基于中间件的路由保护」这节课中我会学到什么?

使用 Next.js 中间件和身份验证回调,在边缘将未验证身份的用户重定向。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「基于中间件的路由保护」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 在 Next.js App Router 中设置 Auth.js
  2. 会话管理与 useSession 钩子
  3. 凭据提供商与自定义登录
  4. 基于中间件的路由保护
← 返回 React Academy