CORS(Cross-Origin Resource Sharing) & Preflight 란?

2025. 8. 28. 09:55·Etc
728x90

1. CORS란?

  • Cross-Origin Resource Sharing
  • 브라우저 보안 정책(Same-Origin Policy) 때문에
  • 다른 오리진(도메인/포트/스킴) 으로 요청할 때 제약이 생김.
  • 서버가 응답 헤더로 허용을 명시해야 브라우저가 요청 결과를 넘겨줌.

2. 오리진(Origin) 구분

오리진은 스킴 + 도메인 + 포트

  • 같은 오리진: http://localhost:8080 → http://localhost:8080
  • 다른 오리진:
    • http://localhost:8080 → http://localhost:3000 (포트 다름)
    • http://localhost:8080 → https://localhost:8080 (스킴 다름)
    • http://localhost:8080 → https://api.example.com:443 (도메인 다름)

3. 단순 요청(Simple Request)

브라우저가 프리플라이트 없이 바로 요청하는 경우.

조건:

  1. 메서드: GET, POST, HEAD
  2. POST일 때 Content-Type:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  3. 커스텀 헤더 없음 (Authorization, X-* 등 금지)

👉 이 경우 서버는 Access-Control-Allow-Origin만 있으면 OK

예:

GET /data
Origin: <http://localhost:8080>

응답:

200 OK
Access-Control-Allow-Origin: <http://localhost:8080>

4. 프리플라이트 요청 (Preflight Request)

단순 요청 조건을 벗어나면 브라우저는 사전 확인 요청(OPTIONS) 을 먼저 보냄.

예:

fetch("<https://api.example.com/data>", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer token"
  },
  body: JSON.stringify({ a: 1 })
})

➡ 브라우저가 먼저 보냄:

OPTIONS /data
Origin: <http://localhost:8080>
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

서버 응답 예:

204 No Content
Access-Control-Allow-Origin: <http://localhost:8080>
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

그 후에야 브라우저가 실제 POST /data 요청을 전송.


5. 필수 CORS 응답 헤더

  • Access-Control-Allow-Origin: 허용할 Origin
  • Access-Control-Allow-Credentials: 인증/쿠키 포함시 필요
  • Access-Control-Allow-Methods: 허용할 HTTP 메서드
  • Access-Control-Allow-Headers: 허용할 요청 헤더
  • Access-Control-Expose-Headers: 클라이언트에서 접근 가능한 응답 헤더

6. 요약 체크리스트

  • GET/POST(폼형식)/HEAD만 → Access-Control-Allow-Origin만 설정하면 끝.
  • PUT/DELETE/PATCH/JSON/Authorization 등 → 프리플라이트 처리 필수
  • 프리플라이트(OPTIONS) 응답에는 반드시 허용 헤더와 메서드 명시.
  • 개발에서는 Origin을 http://localhost:8080으로 제한, 운영에서는 정확히 필요한 도메인만 허용.

7. Nginx 설정 최소 예시

단순 요청만 처리할 때:

add_header Access-Control-Allow-Origin "<http://localhost:8080>" always;

프리플라이트까지 처리할 때:

add_header Access-Control-Allow-Origin "<http://localhost:8080>" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;

if ($request_method = OPTIONS) {
    return 204;
}
728x90

'Etc' 카테고리의 다른 글

Jenkins Pipline, Gitlab, SSH를 이용한 자동화 배포 방법  (1) 2024.10.24
[Onedrive] 다운로드, 동기화, 업로드 오류  (2) 2024.10.08
Elasticsearch, kibana 설치 및 연동(Zip)  (0) 2024.03.20
AI를 통한 웹 페이지 만들기 (make real tldraw)  (2) 2023.11.28
'Etc' 카테고리의 다른 글
  • Jenkins Pipline, Gitlab, SSH를 이용한 자동화 배포 방법
  • [Onedrive] 다운로드, 동기화, 업로드 오류
  • Elasticsearch, kibana 설치 및 연동(Zip)
  • AI를 통한 웹 페이지 만들기 (make real tldraw)
정주원
정주원
개인블로그
  • 정주원
    Joon.eng
    정주원
  • 전체
    오늘
    어제
    • 분류 전체보기 (83)
      • Linux (43)
      • Windows (0)
      • Network (5)
      • Database (0)
      • Cloud (23)
      • Docker (3)
      • Ansible (2)
      • Language (1)
      • Etc (5)
  • 블로그 메뉴

    • 링크

      • GITLAB(woni)
    • 공지사항

    • 인기 글

    • hELLO· Designed By정상우.v4.10.0
    정주원
    CORS(Cross-Origin Resource Sharing) & Preflight 란?
    상단으로

    티스토리툴바