我正在尝试制作一个中间件来对单独的服务器进行 API 调用,但未能进行重定向/重写。以
/api/proxy
开头的路径应不带该前缀并路由到 API 服务器。
我正在使用 NextJS v.15.1.4、NextAuth 5.0.0-beta.25 和 @rescale/nemo 1.4 来组合(未来)中间件。
我的 middleware.ts 目前看起来像这样:
import { NextResponse } from "next/server";
import { cookies } from 'next/headers';
import { createMiddleware, type MiddlewareFunctionProps } from '@rescale/nemo'
import { auth } from 'auth';
const globalMiddlewares = {
before: async ({ request }: MiddlewareFunctionProps) => {
if (!request.url.includes("api/auth")) {
return;
}
auth()
},
};
const middlewares = {
"/api/proxy/*segments": [
async ({ request, response, context, event, forward, params }: MiddlewareFunctionProps) => {
const sessionCookieName = process.env.NODE_ENV === "development"
? "authjs.session-token"
: "__Secure-next-auth.session-token";
const cookieStore = await cookies();
const bearerToken = cookieStore.get(sessionCookieName);
request.headers.set("Authorization", "Bearer " + bearerToken?.value);
const newHeaders = new Headers(request.headers);
newHeaders.set("Authorization", "Bearer " + bearerToken?.value);
const newResponse = NextResponse.next({
request: {
headers: newHeaders
}
});
forward(newResponse);
},
async ({ request, response, context, event, forward, params }: MiddlewareFunctionProps) => {
const path = params()?.segments?.join("/");
return NextResponse.rewrite(new URL(path, process.env.NEXT_PUBLIC_API_BASE));
}
]
}
// create middleware
export const middleware = createMiddleware(middlewares, globalMiddlewares);
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
}
```
您的
forward(newResponse)
放错了位置,您正在链的中间转发,您可能希望首先修改请求路径。相反,仅在解决标头操作并重写路径之后才链接逻辑。确保删除 /api/proxy
前缀,并将 URL 的其余部分正确添加到 API 服务器。您当前正在尝试使用 request.headers
为代理 API 请求设置标头。这可能容易出错,具体取决于中间件在 Next.js 中处理请求的方式。您可以直接向 API 服务器构造 fetch
请求并处理响应。下面的代码调整了
import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { createMiddleware, type MiddlewareFunctionProps } from "@rescale/nemo";
import { auth } from "auth";
const globalMiddlewares = {
before: async ({ request }: MiddlewareFunctionProps) => {
if (!request.url.includes("api/auth")) {
return;
}
auth();
},
};
const middlewares = {
"/api/proxy/*segments": [
// Middleware function for adding Authorization header
async ({
request,
response,
context,
event,
forward,
params,
}: MiddlewareFunctionProps) => {
const sessionCookieName =
process.env.NODE_ENV === "development"
? "authjs.session-token"
: "__Secure-next-auth.session-token";
const cookieStore = cookies();
const bearerToken = cookieStore.get(sessionCookieName);
if (bearerToken?.value) {
request.headers.set("Authorization", `Bearer ${bearerToken.value}`);
}
// Allow the next middleware in the chain to handle the rewrite
return forward();
},
// Middleware function for rewriting the path to the external API server
async ({
request,
response,
context,
event,
forward,
params,
}: MiddlewareFunctionProps) => {
const path = params()?.segments?.join("/"); // Extract segments after `/api/proxy`
return NextResponse.rewrite(
new URL(path ?? "", process.env.NEXT_PUBLIC_API_BASE)
);
},
],
};
export const middleware = createMiddleware(middlewares, globalMiddlewares);
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};