Middleware үндэс
Хэрэглэгч хуудас руу хүсэлт илгээх үед Next.js сервер хариу өгөхөөс өмнө нэг зүйл тохиолдоно — middleware. Энэ бол хүсэлтийг таслан авч шалгах, өөрчлөх, эсвэл өөр хаяг руу илгээх боломж олгодог тусгай layer юм.
Middleware хэрхэн ажилладаг вэ?
Хэрэглэгч /profile руу орохыг оролдоно
↓
Middleware ажиллана
↓
Нэвтэрсэн үү? ──── Тийм ──→ /profile хуудас харуулна
│
Үгүй
│
↓
/login руу redirect хийнэ
Middleware нь middleware.ts файлд тодорхойлогдоно — энэ файл нь app/ директортой нэг түвшинд, төслийн root-д байрлана:
// middleware.ts ← app/ фолдертой нэг түвшинд!
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
console.log(`Хүсэлт: ${pathname}`);
return NextResponse.next(); // хүсэлтийг үргэлжлүүлэн дамжуулна
}
Суpabase Auth-тай нэвтрэлт шалгах
Хамгийн түгээмэл хэрэглээ бол хамгаалагдсан хуудаснуудад нэвтрэлт шалгах:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { createServerClient } from "@supabase/ssr";
export async function middleware(request: NextRequest) {
const response = NextResponse.next({
request: { headers: request.headers },
});
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => {
response.cookies.set(name, value, options);
});
},
},
},
);
const {
data: { user },
} = await supabase.auth.getUser();
const { pathname } = request.nextUrl;
// хамгаалагдсан хуудсуудад нэвтрэлт шаардана
const protectedRoutes = ["/profile", "/courses"];
const isProtected = protectedRoutes.some((route) =>
pathname.startsWith(route),
);
if (isProtected && !user) {
return NextResponse.redirect(new URL("/login", request.url));
}
// нэвтэрсэн хэрэглэгч login хуудсыг харахаас сэргийлэх
if (pathname === "/login" && user) {
return NextResponse.redirect(new URL("/courses", request.url));
}
return response;
}
matcher — middleware хэрхэн зааглах вэ?
Анхны тохиргоогоор middleware бүх хүсэлтэд ажиллана — статик файл, зураг зэрэгт ч. matcher ашиглан зөвхөн хэрэгтэй замуудад ажиллуулна:
// middleware.ts-н доод хэсэгт нэмнэ
export const config = {
matcher: [
/*
* Дараах замуудыг алгасана:
* - _next/static (статик файл)
* - _next/image (зургийн оновчлол)
* - favicon.ico
* - public фолдерийн файлууд
*/
"/((?!_next/static|_next/image|favicon.ico|public/).*)",
],
};
Эсвэл зөвхөн тодорхой замуудад ажиллуулах:
export const config = {
matcher: ["/profile/:path*", "/courses/:path*", "/login"],
};
:path* гэдэг нь тухайн замын бүх дэд замуудыг хамарна гэсэн утгатай. /courses/:path* нь /courses, /courses/javascript, /courses/javascript/01-intro бүгдийг агуулна.
Дараагийн хичээлд:
Cookie болон Header ашиглан хүсэлтийн мэдээлэл уших, тохируулах аргыг судална. Middleware болон Route Handler дотор хэрхэн ашигладгийг практик жишээгээр ойлгоно.