오늘 정리한 내용은 공식 문서 정리입니다.
미들웨어를 사용하면 요청이 완료되기 전에 코드를 실행할 수 있다. 미들웨어 파일은 프로젝트의 루트 경로에 middleware.js 이름으로 생성하면 된다.
🎈 유스케이스
- 인증 및 권한 부여 : 특정 페이지에 대한 접속 권한을 미들웨어에서 확인 후 접속을 차단하거나 허가할 수 있다.
- 서버사이드 리다이렉트 : 특정 조건에 따라 서버 레벨에서 유저를 리다이렉트할 수 있다.
- 봇 탐지 : 봇 트래픽을 감지하고 차단하여 리소스 보호가 가능하다.
- 로깅 및 분석 : 모든 페이지 접속 전 미들웨어를 통하도록 설정할 수 있어 요청 데이터에 대한 분석이 가능하다.
👓 미들웨어에 어울리지 않는 상황
- 복잡한 데이터를 가져오거나 조작 : 미들웨어에서직접 데이터를 가져와서 조작하는 목적으로 제작된 것이 아니다. 이는 라우트 핸들러 또는 서버사이드에서 구현하는게 좋다.
- 무거운 계산 작업 : 미들웨어에서 무거운 작업을 진행하게 되면 페이지 로드가 지연될 수 있다. 무거운 계산 작업은 라우트 핸들러 내에서 수행되어야 한다.
- 광범위한 세션 관리 : 세션 관리를 할 수 있긴 하지만 제한적으로만 관리되어져야 한다.
- 데이터베이스 직접 접근 : 데이터베이스에 대한 접근은 라우트 핸들러나 서버에서 수행하는 것이 좋다.
🛒 경로 매칭
따로 특정 경로를 매칭하지 않으면 모든 경로에 대해 호출된다.
아래는 호출 순서이다.
- next.config.js의 headers
- next.config.js의 redirects
- 미들웨어
- next.config.js의 beforeFiles
- 파일시스템 라우트
- next.config.js의 afterFiles
- 동적 라우트
- next.config.js의 fallback
📯 Matcher
미들웨어 파일 내에서 config 변수를 export 하면 된다.
export const config = {
matcher: ['/about/:path*', '/dashboard/:path*'],
}
아래와 같이 정규식을 사용할 수 있다.
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico, sitemap.xml, robots.txt (metadata files)
*/
'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
],
}
matcher 구성방법
- 반드시 ‘/’ 로 시작해야 한다.
- 경로에 파라미터를 포함할 수 있다 : /about/:path
- 파라미터에 수정자를 가질 수 있다 : /about/:path*
- *는 0 또는 그 이상
- ?는 0 또는 한개
- +는 한 개 이상
- /about/(.*) 와 같다.
🚩 NextResponse
- redirect 및 rewrite 제공
- 응답 쿠키, 응답 헤더 설정 가능
✨ redirect는 다른 주소로 이동하는 것, rewrite는 주소는 동일하고 서버 처리만 다른 주소로 요청
💊 쿠기
Next.js는 NextRequest와 NextResponse에서 쿠키 확장을 통해 쿠키에 액세스하고 조작할 수 있는 편리한 방법을 제공한다.
더보기
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Assume a "Cookie:nextjs=fast" header to be present on the incoming request
// Getting cookies from the request using the `RequestCookies` API
let cookie = request.cookies.get('nextjs')
console.log(cookie) // => { name: 'nextjs', value: 'fast', Path: '/' }
const allCookies = request.cookies.getAll()
console.log(allCookies) // => [{ name: 'nextjs', value: 'fast' }]
request.cookies.has('nextjs') // => true
request.cookies.delete('nextjs')
request.cookies.has('nextjs') // => false
// Setting cookies on the response using the `ResponseCookies` API
const response = NextResponse.next()
response.cookies.set('vercel', 'fast')
response.cookies.set({
name: 'vercel',
value: 'fast',
path: '/',
})
cookie = response.cookies.get('vercel')
console.log(cookie) // => { name: 'vercel', value: 'fast', Path: '/' }
// The outgoing response will have a `Set-Cookie:vercel=fast;path=/` header.
return response
}
⚽ 헤더
NextResponse API를 사용해서 요청 및 응답 헤더를 설정할 수 있다.
더보기
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// Clone the request headers and set a new header `x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-hello-from-middleware1', 'hello')
// You can also set request headers in NextResponse.next
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
})
// Set a new response header `x-hello-from-middleware2`
response.headers.set('x-hello-from-middleware2', 'hello')
return response
}
🧵 CORS
미들웨어에서 CORS 헤더를 설정하여 단순 요청 및 사전 프리플라이트 요청을 포함한 CORS을 허용할 수 있다.
더보기
import { NextRequest, NextResponse } from 'next/server'
const allowedOrigins = ['https://acme.com', 'https://my-app.org']
const corsOptions = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
export function middleware(request: NextRequest) {
// Check the origin from the request
const origin = request.headers.get('origin') ?? ''
const isAllowedOrigin = allowedOrigins.includes(origin)
// Handle preflighted requests
const isPreflight = request.method === 'OPTIONS'
if (isPreflight) {
const preflightHeaders = {
...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
...corsOptions,
}
return NextResponse.json({}, { headers: preflightHeaders })
}
// Handle simple requests
const response = NextResponse.next()
if (isAllowedOrigin) {
response.headers.set('Access-Control-Allow-Origin', origin)
}
Object.entries(corsOptions).forEach(([key, value]) => {
response.headers.set(key, value)
})
return response
}
export const config = {
matcher: '/api/:path*',
}
코드 출처 https://nextjs.org/docs/app/building-your-application/routing/middleware
'학습 정리(공식문서,강의) > Next.js' 카테고리의 다른 글
11. 서버 액션 (0) | 2024.12.24 |
---|---|
10. 데이터 페칭과 캐싱 (0) | 2024.12.16 |
8. 리다이렉트와 라우트 핸들러 (0) | 2024.12.06 |
7. Linking and Navigating (0) | 2024.12.03 |
6. 인터셉팅 라우트 (0) | 2024.11.29 |