Как работают middleware в Next.js
Что проверяют
Знаете ли вы, где именно в конвейере запроса выполняется этот код, и чего в нём делать нельзя. Практический смысл: кандидаты регулярно строят на middleware авторизацию и получают дыру в безопасности.
Как отвечать
- Начните с версии. В Next.js 16 middleware переименован в proxy: файл
proxy.tsв корне или вsrc, на одном уровне сapp, ровно один на проект. Логику разносят по модулям и импортируют в него. - Экспортируется функция
proxy(именованная или дефолтная) плюсexport const config = { matcher: [...] }. Код выполняется до маршрутизации и до отдачи кэша. - Рантайм по умолчанию Node.js (до 16 версии был Edge), опцию
runtimeв этом файле задавать нельзя. - Возвращают
NextResponse.next(),.redirect(),.rewrite()или готовыйResponse. Заголовки запроса пробрасывают черезNextResponse.next({ request: { headers } }), куки черезrequest.cookiesиresponse.cookies. - Тяжёлая работа запрещена: походы в БД бьют по каждому переходу, а опции кэширования
fetchтут не действуют. Позиция документации: только оптимистичная проверка вроде наличия куки сессии, реальная авторизация в слое данных.
import { NextResponse, type NextRequest } from "next/server";
export function proxy(req: NextRequest) {
if (!req.cookies.get("session")) {
return NextResponse.redirect(new URL("/login", req.url));
}
return NextResponse.next();
}
export const config = { matcher: ["/account/:path*"] };Где спотыкаются
Считают middleware единственным барьером авторизации. Уязвимость CVE-2025-29927 позволяла обойти его заголовком x-middleware-subrequest, так что проверка прав обязана дублироваться в обработчике роута и в слое данных.
Строят matcher в рантайме или собирают из переменных: значение читается статически при сборке, годятся только литералы.
Забывают ограничить область и запускают функцию на статике и префетчах. Отсюда жалобы на медленную навигацию.
Меняют request.headers напрямую и ждут, что страница увидит правку. Мутация никуда не доедет, нужен новый объект заголовков в NextResponse.next.