Next.js 中间件认证
介绍
在构建现代 Web 应用程序时,身份验证和授权是至关重要的功能。Next.js 提供了强大的中间件功能,允许你在请求到达页面之前执行逻辑,例如验证用户是否已登录或检查用户权限。通过中间件,你可以轻松地保护路由,确保只有经过身份验证的用户才能访问特定页面。
本文将逐步介绍如何在 Next.js 中使用中间件进行身份验证与授权,并通过实际案例展示其应用场景。
什么是 Next.js 中间件?
Next.js 中间件是一种在请求到达页面之前运行的函数。它可以用于执行各种任务,例如身份验证、日志记录、重定向等。中间件在 _middleware.ts
或 _middleware.js
文件中定义,并放置在 pages
或 api
目录中。
创建中间件
首先,我们需要创建一个中间件文件。假设我们有一个需要保护的页面 /dashboard
,我们可以在 pages/dashboard/_middleware.ts
中创建中间件。
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('authToken');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
在这个示例中,我们检查请求的 cookies 中是否存在 authToken
。如果不存在,我们将用户重定向到登录页面 /login
。如果存在,我们允许请求继续到 /dashboard
页面。
中间件的实际应用
假设我们有一个电子商务网站,用户需要登录才能访问他们的购物车页面 /cart
。我们可以使用中间件来保护这个页面。
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('authToken');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
将上述代码放置在 pages/cart/_middleware.ts
中,当未登录用户尝试访问 /cart
时,他们将被重定向到 /login
页面。
中间件的进阶用法
除了简单的重定向,中间件还可以用于更复杂的场景,例如基于角色的访问控制。假设我们有一个管理面板 /admin
,只有管理员用户可以访问。
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('authToken');
const role = request.cookies.get('userRole');
if (!token || role !== 'admin') {
return NextResponse.redirect(new URL('/unauthorized', request.url));
}
return NextResponse.next();
}
在这个示例中,我们不仅检查用户是否登录,还检查用户的角色是否为 admin
。如果用户不是管理员,他们将被重定向到 /unauthorized
页面。
总结
Next.js 中间件提供了一种灵活且强大的方式来保护你的应用程序路由。通过中间件,你可以在请求到达页面之前执行身份验证和授权逻辑,确保只有经过验证的用户才能访问特定页面。
在实际应用中,中间件可以用于各种场景,例如简单的重定向、基于角色的访问控制等。通过合理使用中间件,你可以大大提高应用程序的安全性和用户体验。
附加资源
练习
- 创建一个中间件,保护
/profile
页面,确保只有登录用户才能访问。 - 扩展中间件功能,使其能够根据用户角色(例如
user
或admin
)动态重定向到不同的页面。