설명
middleware.ts는 Next.js에서 애플리케이션의 특정 경로 요청에 대해 공통적으로 실행할 작업즉 middleware 를 정의하여 요청(Request)이 처리되기 전에 실행됩니다.
직접적으로 response 및 request / response header 헤더를 수정하거나 rewriting, redirecting 등을 처리 할 수 있습니다.
프로젝트 루트 즉 쉽게 pages나 app 과 같은 레벨에서 작성해서 사용합니다.
주요 예시
1. 인증 및 권한 부여 (Authentication and Authorization)
특정 페이지나 API 경로에 대한 액세스 권한을 부여하기 전에 사용자 신원을 확인하거나 세션 쿠키를 확인 할 수 있습니다.
2. 서버 측 redirects (Server-Side Redirects)
특정 조건(예: 로케일, 사용자 역할)에 따라 서버 수준에서 사용자를 redirect 할 수 있습니다.
ex) 사용자 인증 및 redirects
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export function middleware(req: NextRequest) {
const token = req.cookies.get("authToken"); // JWT 쿠키 확인
if (!token) {
return NextResponse.redirect(new URL("/auth/login", req.url));
}
return NextResponse.next(); // 인증 통과
}
3. 경로 재작성 (Path Rewriting)
요청 경로를 동적으로 변경하여 다른 페이지나 API 로 연결할 수 있습니다. A/B 테스트, 기능 롤아웃, 혹은 레거시 URL을 처리할 때 사용할 수 있습니다
ex) A/B 테스트
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const url = request.nextUrl.clone();
// 랜덤하게 A/B 테스트 분류
const isGroupA = Math.random() < 0.5;
// A 그룹은 /new-design으로, B 그룹은 /old-design으로 경로 재작성
url.pathname = isGroupA ? '/new-design' : '/old-design';
return NextResponse.rewrite(url);
}
ex) 레거시 경로 처리
export function middleware(request: NextRequest) {
const url = request.nextUrl.clone();
if (url.pathname.startsWith('/blog')) {
url.pathname = url.pathname.replace('/blog', '/posts'); // 새로운 경로로 변경
return NextResponse.rewrite(url);
}
return NextResponse.next(); // 통과
}
※ 용어 정리
- A/B 테스트: 두 가지 콘텐츠를 비교하여 방문자/뷰어가 더 높은 관심을 보이는 버전을 확인하는 테스트 로 분할 테스트 또는 버킷 테스트라고도 합니다
- 기능 롤아웃: 개발자가 사용자 기반에 새로운 기능을 점진적으로 출시하는 기능 관리 전략
4. 봇 감지 (Bot Detection)
악성 봇 트래픽을 차단하여 서버 리소스를 보호하고, 적법한 사용자를 위한 성능을 유지합니다.
ex) 봇 감지 및 차단
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const userAgent = request.headers.get('user-agent') || '';
// 특정 User-Agent를 가진 요청 차단
const isBot = /bot|crawl|spider|scraper|curl/i.test(userAgent);
if (isBot) {
return NextResponse.json(
{ message: 'Access denied: Bots are not allowed.' },
{ status: 403 }
);
}
return NextResponse.next();
}
5. 로깅 및 분석 (Logging and Analytics)
페이지나 API가 요청을 처리하기 전에 로그를 기록하거나 분석 데이터를 수집할 수 있습니다.
주의 사항
1. 많은 계산 작업
당연하게도 미들웨어는 가볍고 빠르게 반응해야 하며 무거운 계산 작업이나 장기 실행 프로세스는 페이지 로드가 지연될 수 있습니다.
2. 복잡한 data fetch 및 데이터베이스 작업
middleware 는 직접적인 data fetch 나 database 작업을 위해 설계되지 않았습니다. 대신 이 작업은 Route Handlers or server-side 에서 수행하는 것이 적절합니다.
3. 광범위한 session 관리
middleware 는기본적인 세션 작업을 관리할 수 있지만, 광범위한 세션 관리는 전담 인증 서비스나 경로 핸들러 내에서 관리하는 것이 적절합니다
경로 지정 (Matching)
특정 경로를 정확하게 타겟팅하거나 제외하여 사용 가능합니다.
export const config = {
matcher: [
'/about/:path*',
'/dashboard/:path*',
'/((?!api|_next/static|_next/image|favicon.ico).*)' // 정규식
],
}
조건부 경로
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// '/about' 경로에 대한 처리
if (request.nextUrl.pathname.startsWith('/about')) {
return NextResponse.rewrite(new URL('/about-2', request.url))
}
// '/dashboard' 경로에 대한 처리
if (request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.rewrite(new URL('/dashboard/user', request.url))
}
}
NextResponse
NextResponse 를 사용해 여러 기능을 사용할 수 있습니다.
- redirect : 요청을 다른 URL로 리다이렉트합니다.
- rewrite: 요청 경로를 다른 경로로 변경합니다.
- next: 요청을 미들웨어가 처리하지 않고 다음 단계(페이지, API, 다른 미들웨어)로 넘깁니다.
- json: JSON 형식으로 응답을 반환
cookie 관련
cookie 는 request 에는 Cookie 헤더에 저장되며, response 에는 Set-Cookie 헤더에 저장됩니다.
Next.js는 NextRequest 및 NextResponse의 쿠키 확장을 통해 이러한 쿠키에 액세스하고 조작하는 편리한 방법을 제공합니다.
Request , Response header 세팅
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// 요청 헤더를 복제하고 새로운 헤더 설정
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-hello-from-middleware1', 'hello')
// NextResponse.rewrite 에서도 사용 가능
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
})
// 새로운 응답 헤더 설정
response.headers.set('x-hello-from-middleware2', 'hello')
return response
}
참고
공식문서: https://nextjs.org/docs/14/app/building-your-application/routing/middleware
'nextjs' 카테고리의 다른 글
[Nextjs 15] Route handler cors 설정 (0) | 2025.02.07 |
---|---|
Next.js 환경에서 express, MSW 를 활용한 mock 서버 (1) | 2025.01.05 |
[error] next/image Un-configured Host (0) | 2023.07.10 |
비동기 데이터로 jsx 구성 시 최적화 및 예외 처리 (0) | 2023.06.23 |
커스텀 crousel (nextjs + ts + styled-components) (0) | 2023.04.20 |