NextJS中间件开发问题:API路径重写与请求转发失败
问题分析与修复方案
你的代码存在几个关键问题导致代理转发失效,下面逐一说明并给出修正后的完整代码:
核心问题点
- Request对象不可直接修改:原代码中直接调用
request.headers.set()无效,NextJS的Request实例是不可变的,必须创建新的Request对象来修改头信息。 - Forward方法使用错误:@rescale/nemo的
forward函数需要传递修改后的Request对象,而非NextResponse.next()的结果。 - 重写URL的路径处理不严谨:当
segments为空(比如请求/api/proxy/)时,拼接后的路径为空字符串,会导致目标URL无效。 - Auth调用未异步等待:全局中间件中的
auth()是异步函数,未加await会导致认证逻辑不生效。 - 全局Auth逻辑反转:原代码仅在请求包含
api/auth时调用认证,这与常规的“保护非认证路由”逻辑相反。
修正后的完整代码
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) => { // 非auth路径需要验证身份,auth路径跳过(避免循环认证) if (!request.url.includes("api/auth")) { await auth(); } }, }; const middlewares = { "/api/proxy/*segments": [ async ({ request, 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对象,修改Authorization头 const newRequest = new Request(request); if (bearerToken?.value) { newRequest.headers.set("Authorization", `Bearer ${bearerToken.value}`); } // 传递修改后的请求到下一个中间件 forward(newRequest); }, async ({ params }: MiddlewareFunctionProps) => { const segments = params()?.segments || []; // 处理空路径情况,确保目标URL有效 const path = segments.length > 0 ? segments.join("/") : "/"; const apiBase = process.env.NEXT_PUBLIC_API_BASE; if (!apiBase) { throw new Error("NEXT_PUBLIC_API_BASE环境变量未配置"); } // 构造目标URL并执行重写 const targetUrl = new URL(path, apiBase); return NextResponse.rewrite(targetUrl); } ] } export const middleware = createMiddleware(middlewares, globalMiddlewares); export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], }
关键修改说明
- Request对象修改:通过
new Request(request)创建可修改的请求实例,仅在token存在时设置Authorization头,避免空值导致的请求错误。 - Forward逻辑修正:将修改后的Request传递给
forward,确保后续中间件能拿到更新后的请求信息。 - 路径容错处理:当
segments为空时,默认使用根路径/,避免构造出无效的目标URL。 - Auth逻辑修正:全局中间件中对非auth路径执行认证,并添加
await确保认证完成后再继续请求。 - 环境变量校验:添加对
NEXT_PUBLIC_API_BASE的存在校验,提前暴露配置问题。
内容的提问来源于stack exchange,提问作者droid001
相关产品推荐
相关产品推荐

