/
🌐

SOP and CORS

CORSSOPWeb
Table of contents

동일 좜처 μ •μ±…κ³Ό ꡐ차 좜처 λ¦¬μ†ŒμŠ€ 곡유

ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμ„ ν•˜λ‹€ 보면 ν•œλ²ˆμ€ κ²½ν—˜ν•˜κ²Œ λ˜λŠ” CORS μ΄μŠˆμ™€ SOPλ₯Ό μ„€λͺ…ν•˜λŠ” μ—¬λŸ¬ 글을 μ°Έκ³ ν•˜μ—¬ μ€‘μš”ν•œ 점만 쑰각 λͺ¨μŒ ν•΄λ΄€λ‹€.

SOP(Same-origin policy, 동일 좜처 μ •μ±…)

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진 ν‘œμ€€ μŠ€νŽ™μ˜ λ³΄μ•ˆ κ·œμΉ™μœΌλ‘œ ν•˜λ‚˜μ˜ 좜처(Origin)μ—μ„œ λ‘œλ“œλœ μžμ›(λ¬Έμ„œλ‚˜ 슀크립트)이 ν˜ΈμŠ€νŠΈλ‚˜ ν”„λ‘œν† μ½œ, ν¬νŠΈλ²ˆν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠλŠ” μžμ›κ³Ό μƒν˜Έμž‘μš© ν•˜μ§€ λͺ»ν•˜λ„둝 μš”μ²­ λ°œμƒμ„ μ œν•œν•˜κ³ , 동일 좜처(Same Origin)μ—μ„œλ§Œ 접근이 κ°€λŠ₯ν•œ μ •μ±…

두 URL의 Port(λͺ…μ‹œν•œ 경우), Protocol, Hostκ°€ λͺ¨λ‘ κ°™μ•„μ•Ό Same Origin
"scheme/host/port νŠœν”Œ(tuple)" ν˜Ήμ€ κ·Έλƒ₯ "tuple"이라고 ν•˜κΈ°λ„ ν•œλ‹€.

Internet Explorer μ˜ˆμ™Έμ‚¬ν•­ 😠

IEλŠ” 동일 좜처 정책에 두 가지 μ€‘μš”ν•œ μ˜ˆμ™Έκ°€ 있고 λΉ„ν‘œμ€€μ΄λ©° λ‹€λ₯Έ λΈŒλΌμš°μ €μ—μ„œλŠ” μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • μ‹ λ’°ν•  수 μžˆλŠ” μ‚¬μ΄νŠΈ

    μ–‘μͺ½ 도메인 λͺ¨λ‘κ°€ λ†’μŒ λ‹¨κ³„μ˜ λ³΄μ•ˆ μˆ˜μ€€μ„ 가지고 μžˆλŠ” 경우 동일 좜처 μ œμ•½μ„ μ μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • 포트

    Internet ExplorerλŠ” 동일 좜처 μ •μ±… 검사에 포트λ₯Ό ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.

CORS(Cross-Origin Resource Sharing, ꡐ차 좜처 λ¦¬μ†ŒμŠ€ 곡유)

μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μžμ‹ μ˜ μΆœμ²˜μ™€ λ™μΌν•œ λ¦¬μ†ŒμŠ€λ§Œ 뢈러올 수 있으며, λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό 뢈러였렀면 κ·Έ μΆœμ²˜μ—μ„œ μ˜¬λ°”λ₯Έ CORS 헀더λ₯Ό ν¬ν•¨ν•œ 응닡을 λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€. μ΄λŠ” μ‹œμŠ€ν…œ μˆ˜μ€€μ—μ„œ 타 도메인 κ°„ μžμ› ν˜ΈμΆœμ„ μŠΉμΈν•˜κ±°λ‚˜ μ°¨λ‹¨ν•˜λŠ” 것을 κ²°μ •ν•˜λŠ” 것이닀.

CORSλŠ” μ›ΉνŽ˜μ΄μ§€μƒμ—μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ΄μš©ν•˜μ—¬ XHR(XMLHttpRequest)을 λ‹€λ₯Έ λ„λ©”μΈμœΌλ‘œ λ°œμƒ μ‹œν‚¬ 수 μžˆλ„λ‘ ν•΄μ£ΌλŠ” κΈ°λŠ₯을 가지고 있고 XHR 기반 cross-origin HTTP μš”μ²­μ„ μ΄μš©ν•˜μ—¬ μžμ›μ„ κ³΅μœ ν•΄μ•Ό ν•˜λŠ” λΈŒλΌμš°μ €μ™€ μ„œλ²„ κ°„μ˜ μ•ˆμ „ν•œ ꡐ차 좜처 μš”μ²­ 및 데이터 전솑을 μ§€μ›ν•œλ‹€.

CORS ν•΄κ²°? CORS 이슈 ν•΄κ²°!

ν”νžˆ 'CORS ν•΄κ²°'이라고 ν‘œν˜„ν•˜κΈ° λ•Œλ¬Έμ— CORS μžμ²΄κ°€ μ΄μŠˆλ‚˜ μ—λŸ¬λΌκ³  μ°©κ°ν•˜κΈ° μ‰¬μš΄ 것 κ°™λ‹€.

CORSλŠ” μ—λŸ¬κ°€ μ•„λ‹ˆκ³  μ•žμ„œ 정리 ν–ˆλ“― μ„œλ‘œ λ‹€λ₯Έ origin 간에 λ¦¬μ†ŒμŠ€λ₯Ό μ „λ‹¬ν•˜λŠ” 방식을 μ œμ–΄ν•˜λŠ” λ§€μ»€λ‹ˆμ¦˜μ΄λ‹€.

CORS μ΄μŠˆλŠ” 동일 좜처 μ •μ±…(SOP)에 μ˜κ±°ν•΄ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ μƒν˜Έμž‘μš©μ„ ν•˜μ§€ λͺ»ν•˜λ„둝 막고 κ²½κ³ κ°€ λ°œμƒ ν•˜λŠ” 것 이고, 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ꡐ차 좜처 λ¦¬μ†ŒμŠ€ 곡유(CORS)λ₯Ό μ‚¬μš©ν•΄ 접근을 ν—ˆμš© ν•˜λ„λ‘ μ„€μ •ν•˜λŠ” 것이닀.

κ·ΈλŸ¬λ‹ˆ 'CORS ν•΄κ²°'을 더 λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•˜λ©΄ 'CORS 이슈 ν•΄κ²°'이라 ν•  수 μžˆκ² λ‹€.

CORS 이슈 ν•΄κ²° 방법

μ—¬λŸ¬κ°€μ§€ 방법이 μžˆμ§€λ§Œ CORS 이슈λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 많이 μ‚¬μš©ν•˜λŠ” 방법을 κ°„λ‹¨ν•˜κ²Œ 정리 ν•΄λ΄€λ‹€.

동일 좜처둜 이동

정말 λ‹¨μˆœν•˜κ²Œ 같은 좜처둜 이동 μ‹œν‚€λ©΄ ν•΄κ²°! πŸ€“

μ„œλ²„μ—μ„œ Access-Control-allow-origin 헀더 μΆ”κ°€

μ„œλ²„μ—μ„œ λͺ¨λ“  ν΄λΌμ΄μ–ΈνŠΈμ— μš”μ²­μ— λŒ€ν•œ cross-origin HTTP μš”μ²­μ„ ν—ˆκ°€ν•˜λŠ” Access-Control-Allow-Origin: * 헀더λ₯Ό μΆ”κ°€ν•˜λ©΄ λœλ‹€. ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ μ„€μ •ν•˜λ©΄ 전체 ν˜ΈμŠ€νŠΈμ— λŒ€ν•œ μš”μ²­μ„ ν—ˆμš©ν•˜λŠ” 것이기 λ•Œλ¬Έμ— λ³΄μ•ˆμ— μ·¨μ•½ ν•  수 μžˆλ‹€.

Access-Control-Allow-Origin

Access-Control-Allow-Origin 응닡 ν—€λ”λŠ” 이 응닡이 주어진 originμœΌλ‘œλΆ€ν„°μ˜ μš”μ²­ μ½”λ“œμ™€ 곡유될 수 μžˆλŠ”μ§€λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

Proxy

Proxy ServerλŠ” 헀더λ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μš”μ²­μ„ ν—ˆμš©/κ±°λΆ€ν•˜λŠ” 역할을 μ€‘κ°„μ—μ„œ 해쀄 수 있기 λ•Œλ¬Έμ— 응닡을 μ£Όκ³  λ°›μ„λ•Œ ν”„λ‘μ‹œ μ„œλ²„μ—μ„œ Access-Control-Allow-Origin: * 헀더λ₯Ό λ‹΄μ•„ 응닡해 μ£Όλ©΄ λœλ‹€.

ν”„λ‘œμ νŠΈλ₯Ό 개발 ν•  λ•Œ proxyλ₯Ό μ‚¬μš©ν•˜λŠ” 것은 ν•„μˆ˜μ μΈκ±΄ μ•„λ‹ˆμ§€λ§Œ, λ°±μ—”λ“œμ—μ„œ κ°œλ°œμ„œλ²„λ₯Ό μœ„ν•œ CORS 섀정을 μ•ˆν•΄λ„ λΌμ„œ λΆˆν•„μš”ν•œ μ½”λ“œλ₯Ό μ•„λ‚„ 수 μžˆλ‹€.

webpack-dev-server proxy

ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ webpack-dev-server proxy κΈ°λŠ₯을 μ‚¬μš©ν•˜λ©΄ μ„œλ²„μͺ½ μ½”λ“œλ₯Ό μˆ˜μ •ν•˜μ§€ μ•Šκ³  ν•΄κ²° ν•  수 μžˆλ‹€.

mermaid
sequenceDiagram
Browser->>+WebPackDevSever: μš”μ²­
WebPackDevSever->Proxy:μš”μ²­
Proxy->>Server: μš”μ²­
Server-->>Proxy: 응닡
Proxy-->WebPackDevSever: 응닡
WebPackDevSever-->>-Browser: 응닡

webpack-dev-server의 ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•˜λ©΄, λΈŒλΌμš°μ €μ—μ„œ APIλ₯Ό μš”μ²­ ν•  λ•Œ λ°±μ—”λ“œ μ„œλ²„μ— μ§μ ‘μ μœΌλ‘œ μš”μ²­μ„ ν•˜μ§€ μ•Šκ³ , ν˜„μž¬ κ°œλ°œμ„œλ²„μ˜ μ£Όμ†Œλ‘œ μš”μ²­μ„ ν•˜κ²Œ λœλ‹€. ν•΄λ‹Ή μš”μ²­μ„ λ°›μ•„ κ·ΈλŒ€λ‘œ λ°±μ—”λ“œ μ„œλ²„λ‘œ 전달, λ°±μ—”λ“œ μ„œλ²„μ—μ„œ μ‘λ‹΅ν•œ λ‚΄μš©μ„ λ‹€μ‹œ λΈŒλΌμš°μ €μͺ½μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

CRA(create-react-app)둜 μƒμ„±ν•œ ν”„λ‘œμ νŠΈλΌλ©΄ package.json에 proxy 값을 μ„€μ •ν•˜μ—¬ κ°„λ‹¨ν•˜κ²Œ webpack-dev-server proxy κΈ°λŠ₯을 ν™œμ„±ν™” ν•  수 μžˆλ‹€.

배포 ν• λ•ŒλŠ”

APIκ°€ λ™μΌν•œ λ„λ©”μΈμ—μ„œ μ œκ³΅μ΄λ˜λŠ” κ²½μš°λŠ” 문제 μ—†μ§€λ§Œ API의 도메인과 μ„œλΉ„μŠ€μ˜ 도메인이 λ‹€λ₯΄λ‹€λ©΄ axios의 κΈ€λ‘œλ²Œ baseURL을 μ„€μ •ν•˜λ©΄ λœλ‹€.

javascript
axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? '/' : '{API 도메인}';

process.env.NODE_ENVλŠ” ν˜„μž¬ ν™˜κ²½μ΄ ν”„λ‘œλ•μ…˜μΈμ§€ 개발λͺ¨λ“œμΈμ§€ μ•Œ 수 μžˆλŠ” κ°’ (μ°Έκ³ )

개발 ν™˜κ²½μ—μ„  ν”„λ‘μ‹œ μ„œλ²„ μͺ½μœΌλ‘œ μš”μ²­ν•˜κ³ , ν”„λ‘œλ•μ…˜μ—μ„  μ‹€μ œ API μ„œλ²„λ‘œ μš”μ²­μ„ ν•˜κ²Œ λœλ‹€.

(뢀둝) CORS κ΄€λ ¨ λ³΄μ•ˆ 이슈

CORS의 근본적인 λ³΄μ•ˆλ¬Έμ œλŠ” XHR을 λ‹€λ₯Έ λ„λ©”μΈμœΌλ‘œ λ°œμƒμ‹œν‚¬ λ•Œ, μ‚¬μš©μžμ—κ²Œ ν—ˆκ°€ μš”μ²­μ„ 받지 μ•ŠλŠ”λ‹€λŠ” 것이닀.
μ΄λŸ¬ν•œ λ¬Έμ œλŠ” μ‚¬μš©μžμ˜ μ„Έμ…˜μ„ μ˜€μš©ν•œ μ ‘κ·Όμ œμ–΄μ™€ κ΄€λ ¨λœ λ³΄μ•ˆ 문제λ₯Ό μ•ΌκΈ°ν•  수 μžˆλ‹€. κ³΅κ²©μžκ°€ μ‚¬μš©μžμ˜ μ„Έμ…˜μ„ μ˜€μš©ν•  수 있게 λœλ‹€λŠ” 것은 μ ‘κ·Όμ œμ–΄λ₯Ό μš°νšŒν•˜μ—¬ ν—ˆκ°€λ˜μ§€ μ•Šμ€ λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•  수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

μ ‘κ·Όμ œμ–΄ 우회

μ‚¬μš©μžκ°€ μ†ν•΄μžˆλŠ” λ‚΄λΆ€ λ„€νŠΈμ›Œν¬μ— μ‘΄μž¬ν•˜λŠ” μ›Ήμ‚¬μ΄νŠΈκ°€ β€œAccess-Control-AllowOrigin” 응닡 헀더λ₯Ό 잘λͺ» μ •μ˜ν–ˆμ„ 경우 κ³΅κ²©μžλŠ” μ™ΈλΆ€μ—μ„œ 직접 μ ‘κ·Όν•  수 μ—†λŠ” λ‚΄λΆ€ λ„€νŠΈ μ›Œν¬μ˜ μ›Ήμ‚¬μ΄νŠΈμ— μ ‘κ·Όν•  수 μžˆλ‹€.

CORS와 Web Socket을 μ΄μš©ν•œ 원격 μ‰˜

XHRκ³Ό Web Socket κΈ°μˆ μ„ μ΄μš©ν•˜λ©΄ μ‚¬μš©μžμ˜ λΈŒλΌμš°μ € μ„Έμ…˜μ„ νƒˆμ·¨ν•˜κ³  행동을 μ œμ–΄ν•  수 μžˆλ‹€. λŒ€ν‘œμ μΈ 예둜 μ„Έμ…˜ ν•˜μ΄μž¬ν‚Ή 곡격이 μžˆλ‹€.

CORS와 Web Socket을 μ΄μš©ν•œ μ›Ή 기반

CORS와 Web Socket κΈ°μˆ μ„ μ΄μš©ν•˜λ©΄ μ‚¬μš©μžμ˜ λΈŒλΌμš°μ €λ“€μ„ μ œμ–΄ν•˜μ—¬ λ‹€μ–‘ν•œ 정보λ₯Ό 수 μ§‘ν•˜κ±°λ‚˜ λͺ…령을 내릴 수 μžˆλ‹€.

CORS와 Web Workerλ₯Ό μ΄μš©ν•œ DDoS 곡격

CORS와 Web Workerλ₯Ό μ΄μš©ν•˜λ©΄ 보닀 효과적으둜 DDoS 곡격을 μˆ˜ν–‰ν•  수 μžˆλ‹€.

좜처: HTML5 μ‹ κ·œ μ›Ήμ„œλΉ„μŠ€ ν™˜κ²½μ—μ„œμ˜ λ³΄μ•ˆ 이슈 - ν•œκ΅­μΈν„°λ„·μ§„ν₯원

TL ; DR

  • SOPλŠ” μΆœμ²˜κ°€ λ‹€λ₯Έ μžμ›κ³Ό μƒν˜Έμž‘μš© ν•˜μ§€ λͺ»ν•˜λ„둝 μ œν•œν•œλ‹€.

SOPλŠ” 잠재적으둜 ν•΄λ‘œμšΈ 수 μžˆλŠ” λ‹€λ₯Έ μΆœμ²˜μ—μ„œ κ°€μ Έμ˜¨ λ¦¬μ†ŒμŠ€μ™€ μƒν˜Έμž‘μš©ν•˜λŠ” 것을 μ œν•œν•˜κ³  λΆ„λ¦¬ν•¨μœΌλ‘œμ¨ κ°€λŠ₯ν•œ 곡격 경둜λ₯Ό 쀄여 μ€€λ‹€.

  • CORSλ₯Ό ν—ˆμš© ν•˜λ €λ©΄ μ„œλ²„μ—μ„œ cross-origin HTTP μš”μ²­μ„ ν—ˆκ°€ν•˜λŠ” 헀더λ₯Ό μ„€μ • ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

CORSλŠ” 좜처(도메인, 포트, ν”„λ‘œν† μ½œ)κ°€ λ‹€λ₯Έ μ„œλ²„μ˜ μžμ›μ— μ ‘κ·Όν•  수 μžˆλŠ” κΆŒν•œμ„ λΆ€μ—¬ν•˜λ„λ‘ λΈŒλΌμš°μ €μ— μš”μ²­ν•˜λŠ” λ§€μ»€λ‹ˆμ¦˜, λ¦¬μ†ŒμŠ€κ°€ μžμ‹ μ˜ μΆœμ²˜μ™€ λ‹€λ₯Ό λ•Œ cross-origin HTTP μš”μ²­μ„ μ‹€ν–‰ν•œλ‹€.

  • CORS μ΄μŠˆλŠ” SOP에 μ˜κ±°ν•΄ λ°œμƒν•œλ‹€.

SOP에 μ˜κ±°ν•΄ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€μ™€ μƒν˜Έμž‘μš© ν•˜λŠ” 것이 μ°¨λ‹¨λ˜λŠ”λ° CORSλ₯Ό μ„€μ • ν•¨μœΌλ‘œμ¨ μƒν˜Έμž‘μš©μ΄ κ°€λŠ₯ 해진닀.

  • ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ 개발 κ³Όμ •μ—μ„œλŠ” ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•΄ ν•΄κ²° κ°€λŠ₯ν•˜λ‹€.

λ°±μ—”λ“œ κ°œλ°œμžμ—κ²Œ μš”μ²­ν•΄ μ„œλ²„μ—μ„œ 섀정해도 λ˜μ§€λ§Œ, ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ 사이 ν”„λ‘μ‹œλ₯Ό 톡해 Access-Control-Allow-Origin 헀더λ₯Ό μ„€μ • ν•  수 μžˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ λ°±μ—”λ“œμ—μ„œ λ”°λ‘œ μ„€μ •ν•  ν•„μš”κ°€ 없어진닀!

두 쀄 μš”μ•½

SOPλŠ” 같은 origin을 가진 λ¦¬μ†ŒμŠ€λ§Œ 접근이 κ°€λŠ₯ν•˜λ„λ‘ μ œν•œν•œλ‹€.
CORSλŠ” 도메인 λ˜λŠ” ν¬νŠΈκ°€ μ„œλ‘œ λ‹€λ₯Έ origin 간에 λ¦¬μ†ŒμŠ€λ₯Ό μ „λ‹¬ν•˜λŠ” 방식을 μ œμ–΄ν•˜λŠ” λ§€μ»€λ‹ˆμ¦˜μ΄λ‹€.

reference

ꡐ차 좜처 λ¦¬μ†ŒμŠ€ 곡유 (CORS) - HTTP | MDN

Access-Control-Allow-Origin - HTTP | MDN

동일 좜처 μ •μ±… - μ›Ή λ³΄μ•ˆ | MDN

CORS에 λŒ€ν•œ κ°„λ‹¨ν•œ κ³ μ°° | Velog

SOP, CORS | Velog

CORS 와 해결방법 (express, proxy) | Velog

CORS: Real examples | Velog

NodeJS X CRA (proxy) | Velog

CORS 와 Webpack DevServer Proxy Β· GitBook

CORS - amessinger

ajax - What are the security risks of setting Access-Control-Allow-Origin? | Stack Overflow

HTML5 μ‹ κ·œ μ›Ήμ„œλΉ„μŠ€ ν™˜κ²½μ—μ„œμ˜ λ³΄μ•ˆ 이슈 - ν•œκ΅­μΈν„°λ„·μ§„ν₯원

logo
Things I've Learned