我正在开发一个 Next.js 项目,并尝试在我的应用程序中实现多个中间件。虽然我发现了使用
next-connect
包在 Next.js 中使用单个中间件的示例,但我更喜欢在不依赖任何外部包的情况下实现这一点。
我有一个
middleware.ts
文件,我想在其中定义和使用多个中间件。这是我的 middleware.ts
文件中的代码片段:
import { NextResponse, NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const userId = request.cookies.get('userId')
if (!userId) {
return NextResponse.redirect(new URL('/auth/login', request.nextUrl.origin).href);
}
return NextResponse.next();
}
export const config = {
matcher:'/profile/:path*',
};
她就是我尝试过的:
import { NextResponse, NextRequest } from "next/server";
export function profileMiddleware(request: NextRequest) {
const userId = request.cookies.get("userId");
if (!userId) {
return NextResponse.redirect(
new URL("/auth/login", request.nextUrl.origin).href
);
}
return NextResponse.next();
}
export function authMiddleware(request: NextRequest) {
const userId = request.cookies.get("userId");
if (userId) {
return NextResponse.redirect(
new URL("/", request.nextUrl.origin).href
);
}
return NextResponse.next();
}
export default {
middleware: [
{
matcher: '/profile/:path*',
handler: profileMiddleware,
},
{
matcher: '/auth/:path*',
handler: authMiddleware,
},
],
};
您可以使用中间件链接来实现此目的。以下是实现这一目标的方法:
middlewares
文件夹中创建一个名为 src
的文件夹。stackHandler.ts
文件夹中创建一个名为 middlewares
的文件并将以下内容粘贴到其中:import {
NextMiddleware,
NextResponse
} from "next/server";
export function stackMiddlewares(functions: MiddlewareFactory[] = [], index = 0): NextMiddleware {
const current = functions[index];
if (current) {
const next = stackMiddlewares(functions, index + 1);
return current(next);
}
return () => NextResponse.next();
}
withUser.ts
的文件并将以下内容粘贴到其中:import {
NextFetchEvent,
NextRequest,
NextResponse
} from "next/server";
function getSearchParam(param: string, url: any) {
return url.searchParams.get(param);
}
export const withUser: MiddlewareFactory = (next) => {
return async(request: NextRequest, _next: NextFetchEvent) => {
const pathname = request.nextUrl.pathname;
if (["/profile"]?.some((path) => pathname.startsWith(path))) {
const userId = request.cookies.get("userId");
if (!userId) {
const url = new URL(`/auth/login`, request.url);
return NextResponse.redirect(url);
}
}
return next(request, _next);
};
};
middleware.ts
文件夹中的 src
文件中粘贴以下内容:import {
stackMiddlewares
} from "@/middlewares/stackHandler";
import {
withUser
} from "@/middlewares/withUser";
const middlewares = [withUser];
export default stackMiddlewares(middlewares);
定义 MiddlewareFactory 类型如下(如果不使用 Typescript,请忽略此):
import {
NextMiddleware
} from "next/server";
export type MiddlewareFactory = (middleware: NextMiddleware) => NextMiddleware;
您可以根据需要创建任意数量的中间件,例如
withUser
,方法是创建它们,然后将它们导入到 middlewares.ts
并将它们推送到 middlewares
数组中。