conf의 CORS 관련 블록 전체
add_header, proxy_hide_header, proxy_set_header 각각 안에 들어가는 모든 값의 의미 정리
🔍 1. add_header: 클라이언트 응답용 CORS 헤더
add_header 'Access-Control-Allow-Origin' $allowed_origin always;
| Access-Control-Allow-Origin | 어떤 Origin(도메인)에서 온 요청을 허용할지 명시 |
| $allowed_origin | 미리 set 해둔 변수 (예: https://yourdomain.com)🔒 * 대신 정확한 도메인을 지정해야 쿠키/토큰 허용 가능 |
| always | 오류 응답(4xx/5xx)에도 헤더를 포함시킴 |
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
| Access-Control-Allow-Methods | 허용할 HTTP 메서드들 |
| 값 | 브라우저가 preflight 요청(OPTIONS)으로 이 메서드들 허용 여부를 확인함 |
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin, User-Agent, X-Requested-With, x-internal-api-key' always;
| Authorization | JWT, Bearer 토큰 등 인증 정보를 보내기 위해 필요 |
| Content-Type | 보낼 데이터 형식 (예: application/json) |
| Accept | 원하는 응답 타입 (예: JSON, XML 등) |
| Origin | 요청의 출처 도메인 (브라우저 자동 포함) |
| User-Agent | 클라이언트 종류 정보 (브라우저, 앱 등) |
| X-Requested-With | Ajax 요청임을 나타냄 (예: XMLHttpRequest) |
| x-internal-api-key | 사용자 정의 API 키 헤더 |
add_header 'Access-Control-Allow-Credentials' 'true' always;
| 클라이언트가 쿠키, 세션, Authorization 헤더 같은 **자격 증명(credentials)**을 포함할 수 있게 허용 |
⚠️ 이걸 썼다면 Origin은 반드시 * 말고 정확한 도메인만 사용해야 함
⭐⭐⭐ Origin은 반드시 * 말고 정확한 도메인만 사용해야 함 => 어떻게?
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
| Content-Length | 응답 데이터의 크기 (바이트 단위) |
| Content-Range | 부분 응답 시 범위 지정 (bytes 0-99/200) |
| → Expose-Headers | 클라이언트 JavaScript가 이 헤더들을 접근할 수 있도록 허용 |
🔍 2. proxy_hide_header: 백엔드 응답 헤더 숨김
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Credentials';
proxy_hide_header 'Access-Control-Allow-Headers';
목적 : proxy가 백엔드(n8n)로부터 받은 응답 헤더 중 CORS 관련 헤더를 숨김
이유 : 백엔드가 잘못된 CORS 헤더(* 등)를 보낼 경우 이를 차단하고,
우리가 add_header로 설정한 정확한 헤더만 브라우저에게 보이게 하기 위해서
🔴 후기(에러 확인)
n8n응답 받을 때 이거 안해줬더니, 이런 오류가 뜸. 저거 해주니까 사라짐..
Access to fetch at 'https://example.com/webhook/examplewebhook'
from origin 'https://example.com' has been blocked by CORS policy:
The 'Access-Control-Allow-Origin' header contains multiple values
'https://example.com, *', but only one is allowed.
해결 참고링크
N8n CORS middleware config bug Causing Multiple Allow-Origin headers being sent
Posting this here because it might save someone hours of pain. Long story short, as many users have pointed out, n8n doesn’t handle CORS headers on preflights, which can make it hard to make requests from the frontend (Add ability to set CORS allow-list
community.n8n.io
🔍 3. proxy_set_header: n8n에 전달할 요청 헤더 설정
proxy_set_header Origin $scheme://$host:$server_port;
| Origin | 프록시가 요청하는 출처(Origin)를 현재의 프로토콜/호스트/포트로 위장 |
| 예 | https://test.kr:10300 |
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
| X-Real-IP | 실제 클라이언트의 IP 주소 (직접 연결된 것 기준) |
| X-Forwarded-For | 프록시 체인을 따라온 IP들의 목록(클라이언트 → 프록시1 → 프록시2 ... 의 IP들 누적) |
proxy_set_header Host $http_host;
원래 요청의 Host 헤더를 유지해서 n8n이 정확한 도메인 기준으로 응답할 수 있도록 함
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
- WebSocket 또는 HTTP Keep-Alive 연결을 유지하기 위한 설정
- Upgrade, Connection: upgrade → WebSocket 핸드셰이크 처리 가능
✅ 한 줄 요약
| 블록 | 역할 |
| add_header | 브라우저에게 보일 CORS 허용 정보 직접 명시 |
| proxy_hide_header | n8n이 보내는 CORS 헤더는 숨기고 |
| proxy_set_header | n8n에 보내는 요청 헤더는 위장 및 보완 |
| proxy_http_version 등 | WebSocket 및 연결 안정성 확보 |
질문 : $remote_addr $proxy_add_x_forwarded_for; $host:$server_port $scheme 이런 $ 이 표시가 있는 건 어디에서 설정 해주고 있는거야 ??
답변 : $remote_addr, $proxy_add_x_forwarded_for, $host, $server_port, $scheme 같은 $로 시작하는 애들은 "Nginx 내장 변수"(built-in variable)들이야.
✅ $변수는 누가 설정하냐?
Nginx가 요청을 받을 때 자동으로 채워주는 시스템 변수들이야.
즉, 우리가 직접 어디선가 정의하지 않아도,
Nginx가 요청을 분석해서 내부적으로 자동으로 만들어줘.
🔍 주요 $변수 설명
| 변수 | 의미 | 예시 값 |
| $remote_addr | 클라이언트의 IP 주소 | 192.168.0.12 |
| $proxy_add_x_forwarded_for | X-Forwarded-For에 기존 값 + 현재 IP 추가 | 192.168.0.12, 10.0.0.2 |
| $host | 요청한 Host 헤더 값 | test.kr |
| $server_port | 요청이 들어온 Nginx의 포트 | 10300 |
| $scheme | 접속 방식 (http or https) | https |
| $request_uri | 요청 경로와 쿼리 | /api/test?id=123 |
| $http_user_agent | 브라우저 종류 (User-Agent 헤더) | Mozilla/5.0... |
| $request_method | 요청 메서드 (GET, POST 등) | POST |
📌 변수는 어디서 쓸 수 있어?
- proxy_set_header, add_header 등에 넣어서 → 동적인 응답 헤더 구성
- access_log 포맷 정의
- rewrite, if, map 조건문 등에서 사용 가능
🎯 직접 정의하는 경우도 있긴 해
예를 들어 이런 식으로:
set $allowed_origin "https://test.kr";
이건 사용자 정의 변수고, $allowed_origin 같은 건 우리가 직접 만들어서 쓰는 거야.
✅ 정리
| 종류 | 예시 | 설정 위치 |
| 내장 변수 | $remote_addr, $host, $scheme | Nginx가 자동 생성 |
| 사용자 정의 변수 | $allowed_origin, $backend_url | 우리가 set으로 명시해야 함 |
'공부 > Infra' 카테고리의 다른 글
| Access to XMLHttpRequest at ... from origin ... has been blocked by CORS policy: Response to preflight request doesn't pass access control check: (1) | 2025.07.24 |
|---|---|
| CORS (4) | 2025.07.24 |
| Nginx에서 HTTPS로 받고, 내부 Kestrel에서는 HTTP로 처리해도 괜찮을까? (0) | 2025.02.13 |
| chown과 chmod의 의미 (0) | 2025.02.12 |
| --restart=unless-stopped (0) | 2025.02.04 |