설명
route handler 를 통한 응답 헤더 cors 설정 방법 공식문서에서는 middleware.ts 및 next.conifg.ts 에서 설정하는 것을 추천
cors 헤더 설명
Access-Control-Allow-Origin
- 요청을 허용할 출처(origin)를 지정
*
는 모든 출처를 허용하지만, 인증된 요청(예: 쿠키 포함 요청)에는 사용 불가합니다.
Access-Control-Allow-Methods
- 서버가 허용하는 HTTP 메서드(GET, POST, PUT 등)를 지정
- 기본적으로 서버는 GET, HEAD, POST만 허용
Access-Control-Allow-Headers
- 클라이언트가 요청할 때 사용할 수 있는 요청 헤더를 지정
Access-Control-Allow-Credentials
- 인증 정보를 포함한 요청(예: 쿠키, HTTP 인증 헤더)을 허용할지 여부를 설정
- true로 설정하려면, Access-Control-Allow-Origin은
*
가 아닌 특정 출처여야 합니다.
1. route.ts 에서 직접 설정
preflight 확인을 위한 OPTIONS 요청에서 헤더 제대로 지정되지 않은 경우 cors 오류가 발생할 수 있으므로 OPTIONS 요청에 대한 내용을 각각 구현해야 하는 불편함이 존재
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
const response = new NextResponse(JSON.stringify({ message: "Hello" }), {
status: 200,
});
response.headers.set("Access-Control-Allow-Origin", "*");
response.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
response.headers.set("Access-Control-Allow-Headers", "Content-Type");
return response;
}
2. middleware.ts 에서 설정
모든 요청에 같은 헤더를 적용 하므로 예로 Access-Control-Allow-Credentials 가 필요하지 않는 요청의 경우를 특정하고 제외하기에 불편함이 있음
// middleware.ts
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*',
}
3. next.conifg.ts headers (최종 적용 방법)
next.conifg.ts 에서 각 경로에 따라 헤더를 다르게 설정하고 덮어쓸 수 있어 각기 다른 헤더를 적용 가능
import type { NextConfig } from "next";
import { env } from "process";
const allowedOrigin = env.ALLOWED_ORIGIN || "";
// 공통 헤더 형식
const BASIC_HEADERS = [
{
key: "Access-Control-Allow-Origin",
value: allowedOrigin,
},
{
key: "Access-Control-Allow-Methods",
value: "GET, POST, PUT, DELETE, PATCH, OPTIONS",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
];
const nextConfig: NextConfig = {
/* config options here */
async headers() {
return [
// 전체 라우트에 공통헤더 + Access-Control-Allow-Credentials 적용
{
source: "/api/:path*",
headers: [
{
key: "Access-Control-Allow-Credentials",
value: "true",
},
...BASIC_HEADERS,
],
},
// /api/auth/ 라우트에 공통헤더 적용
{
source: "/api/auth/:path*",
headers: BASIC_HEADERS,
},
// /api/auth/login 라우트만 Access-Control-Allow-Credentials 적용
{
source: "/api/auth/login",
headers: [
{
key: "Access-Control-Allow-Credentials",
value: "true",
},
...BASIC_HEADERS,
],
},
];
},
};
export default nextConfig;
참고
https://nextjs.org/docs/app/building-your-application/routing/route-handlers#cors
https://nextjs.org/docs/app/building-your-application/routing/middleware#cors
https://nextjs.org/docs/app/api-reference/config/next-config-js/headers#cors
'nextjs' 카테고리의 다른 글
[Nextjs 15] Uncaught Error: Switched to client rendering because the server rendering errored 에러 (0) | 2025.02.07 |
---|---|
Next.js 환경에서 express, MSW 를 활용한 mock 서버 (1) | 2025.01.05 |
nextjs middleware.js | ts (0) | 2024.11.26 |
[error] next/image Un-configured Host (0) | 2023.07.10 |
비동기 데이터로 jsx 구성 시 최적화 및 예외 처리 (0) | 2023.06.23 |