Next.js 13.4 App Router中如何传递修改后的请求至后续路由?
解决Next.js 13.4 App Router中间件中request.locals.user无法传递的问题
问题描述
基于Next.js 13.4 App Router开发项目时,在中间件中自定义了CustomNextRequest接口,将令牌验证后获取的用户对象存入request.locals.user,但后续API路由处理器中访问该属性时始终返回undefined,无法获取用户数据。
原因分析
- Next.js App Router的中间件与路由处理器使用独立的Request实例,直接修改中间件传入的
request对象的locals属性,不会自动同步到后续路由处理器的request中。 - 若目标路由不在middleware的
matcher匹配范围内,中间件根本不会执行,也会导致locals无数据。 - TypeScript类型定义的扩展方式不正确,可能导致路由处理器无法识别
locals属性。
解决方案
1. 修正中间件的数据传递逻辑
不要直接修改原request对象,而是创建新的Request实例并附加locals数据,通过NextResponse.next()传递给后续路由:
// 替换中间件中原return NextResponse.next();的逻辑 const newRequest = new Request(request.url, request); // 确保user.user有值,可先打印验证 console.log("待存储的用户数据:", user.user); newRequest.locals = { user: user.user }; return NextResponse.next({ request: newRequest });
2. 确保目标路由在匹配范围内
检查config.matcher是否包含你的目标路由,若不在则更新匹配规则:
export const config = { matcher: ["/api/admin/:path*", "/api/usersales/:path*", "/api/your-target-route/:path*"], };
3. 规范TypeScript类型扩展
避免自定义独立的CustomNextRequest接口,直接扩展Next.js内置的NextRequest类型:
// middleware.ts中 import { NextRequest } from "next/server"; import { UserAdminInfo, UserPortalInfo } from "./app/libs/types"; type User = UserAdminInfo | UserPortalInfo; // 扩展NextRequest类型,添加locals属性 declare module "next/server" { interface NextRequest { locals: { user?: User; }; } } // 中间件函数参数直接使用扩展后的NextRequest export default async function middleware(request: NextRequest) { // ... 原有验证逻辑 const newRequest = new Request(request.url, request); newRequest.locals = { user: user.user }; return NextResponse.next({ request: newRequest }); }
路由处理器中直接使用扩展后的NextRequest:
import prisma from "@/app/libs/prismadb"; import { NextRequest, NextResponse } from "next/server"; export async function PUT( request: NextRequest, { params: { id } }: { params: { id: string } }, ) { if (request.locals.user) { console.log(request.locals.user); // 现在可正常获取用户数据 } // ... 原有业务逻辑 }
4. 验证接口返回数据
确保/api/checktoken接口返回的user.user有有效值,可在中间件中添加日志确认:
const user = await response.json(); console.log("checktoken接口返回数据:", user);
如果user.user本身为undefined,需先修正令牌验证接口的返回格式。
内容的提问来源于stack exchange,提问作者khalid dahir
相关产品推荐
相关产品推荐

