미들웨어(middleware)란, 처음 유저가 보낸 요청과 종착지 사이에 있는 소프트웨어이다. 유저의 정보를 DB에 보낼 때 중간에서 검증 함수를 거친다면, 그 함수가 미들웨어이다.
Next.js
는 간편한 미들웨어 구현을 제공한다. pages
디렉토리 내의 어디든지 _middleware
이름을 가진 파일을 생성하면 된다.
- 경로
pages
└profile
└index.ts
└index.ts
└_middleware.ts
_middleware.ts
파일 내에서 middleware()
함수를 생성한다.
import type { NextRequest, NextFetchEvent } from "next/server";
export function middleware(request: NextRequest, event: NextFetchEvent) {
console.log("전역 미들웨어입니다.");
}
전역 미들웨어로 설정하면 유저가 페이지를 이동할 때마다 작동한다.
profile
과 sales
로 이동할 때마다 전역 미들웨어가 작동하는 것을 볼 수 있다.
특정 페이지에서만 작동하는 미들웨어 역시 간단하게 만들 수 있다. 해당 페이지 디렉토리 내에 생성하면 된다.
- 경로
pages
└profile
└index.ts
└_middleware.ts
└index.ts
유저가 profile
로 이동할 때마다 작동한다.
유저가 특정 api
에 요청을 보낼 때만 작동하는 미들웨어를 만들고 싶다면 pages/api
디렉토리에 _middleware
파일을 만든다.
middleware
request
는 여러 파라미터를 가지고 있다. request.ua
(user agent) 내부에 isBot
이 담겨 있으며, boolean
으로 표현된다. 이것으로 홈페이지에 접근한 대상이 봇일 때 렌더링 전에 차단할 수 있다.
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(request: NextRequest, event: NextFetchEvent) {
if (req.ua?.isBot) {
return new Response("bot은 접근 불가.", { status: 403 });
}
}
request
의 cookies
를 이용해, 쿠키(혹은 세션)가 없다면 로그인 페이지로 강제 이동시킨다. 대문 페이지로 접근을 시도했어도, 해당 페이지가 렌더링 되기 전에 로그인 페이지로 리다이렉트하므로 잠깐 동안의 페이지 노출까지 방지할 수 있다.
import type { NextRequest, NextFetchEvent } from "next/server";
import { NextResponse } from "next/server";
export function middleware(request: NextRequest, event: NextFetchEvent) {
if (!request.url.includes("/login") && !request.cookies.session) {
return NextResponse.rewrite(new URL("/login", request.url));
}
}
접근한 페이지가 /login
을 포함하지 않은 페이지거나 session
이 없는 경우 baseurl/login
으로 리다이렉트한다.
new URL(input<string\>, base)
input이 상대 주소라면 base를 필요로 한다. 절대 주소라면 base는 무시된다.example
const myURL = new URL('/foo', 'https://example.org/');
=>https://example.org/foo
const myURL = new URL('https://Example.com/', 'https://example.org/');
=>https://example.com/
참고
노마드 코더 - 캐럿마켓 클론코딩
Next.js Docs - Middelware
Next.js Docs - NextRequest
Node.js Docs - URL
전 에러 뜨는데,,,
error - Nested Middleware is not allowed, found:
pages/_middleware
미들웨어 제대로 동작하시나요 ??