๐Ÿฅ CORS๋Š” ์™œ ์ƒ๊ฒผ์„๊นŒ์š”?

MISO :-)

๐Ÿฅ CORS๋Š” ์™œ ์ƒ๊ฒผ์„๊นŒ์š”?

2023๋…„ 02์›” 10์ผ

8๋ถ„

0๋ช…์˜ ์‚ฌ๋žŒ์ด ์ฝ์–ด๋ดค์–ด์š”

CORS๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋Š” ํ•˜๋‚˜์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค.


์›น์‚ฌ์ดํŠธ๋Š” ๋ณด์•ˆ์„ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ถœ์ฒ˜์ธ ๊ณณ๊ณผ๋Š” ํ†ต์‹ ์„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ CORS ์•ˆ์˜ ๊ทœ์น™๋“ค์„ ํ†ต๊ณผํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ ์ถœ์ฒ˜์ธ ๊ณณ๊ณผ ํ†ต์‹ ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


์ €ํฌ๊ฐ€ ์ž์ฃผ ๋ณด๋Š” CORS ์—๋Ÿฌ๋Š” ์„œ๋ฒ„๊ฐ€ ์ด ๊ทœ์น™์„ ์ง€ํ‚ค์ง€ ๋ชปํ•ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ทœ์น™ ์ข€ ์ง€์ผœ์ค„๋ž˜? ํ•˜๊ณ  ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

CORS๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ทœ์น™์€ Access-Control-Allow-Origin๋ฅผ ์„œ๋ฒ„์™€ ๋™์ผํ•œ URL๋กœ ๋งž์ถ”๋Š” ๊ฒƒ ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.


(์ž์„ธํ•œ ๋‚ด์šฉ์€ ๐ŸŒธ CORS ๋™์ž‘๊ณผ์ • ์ •๋ฆฌ ์— flowchart๋กœ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.)


์•„๋งˆ ์ด ๊ธ€์„ ์ฝ์œผ์‹œ๋Š” ๋ถ„๋“ค์€ ๋Œ€๋ถ€๋ถ„ CORS๊ฐ€ ๋ณด์•ˆ์„ ์œ„ํ•ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ CORS๋Š” ์˜ค๋žœ ๊ธฐ๊ฐ„ ๋ฐœ์ „๋˜์–ด ์˜จ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.


์ฒ˜์Œ๋ถ€ํ„ฐ CORS ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋ธŒ๋ผ์šฐ์ €์— ์ ์šฉ์‹œํ‚จ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด ๋ฌธ์žฅ์„ ๋“ฃ๊ณ  ๊ถ๊ธˆ์ฆ์„ ๋Š๋ผ์…จ๋‹ค๋ฉด ์ด ๊ธ€์ด ๋„์›€๋˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ณผ๊ฑฐ์˜ ์ธํ„ฐ๋„ท

์ถœ์ฒ˜: http://www.overyourhead.co.uk/2011/12/1980s-internet.html

1980๋…„๋Œ€์˜ ์ธํ„ฐ๋„ท์—๋Š” ์ž˜ ์ •์˜๋œ ํ’๋ถ€ํ•œ ์ฝ˜ํ…์ธ ๊ฐ€ ์—†์—ˆ๊ณ  ์ผ๋ฐ˜ ํ…์ŠคํŠธ์™€ ์ผ๋ฐ˜ ํŒŒ์ผ๋งŒ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


์‹œ๊ฐ„์ด ์ง€๋‚œ 1989๋…„์—” Tim Berners-Lee๊ฐ€ ๋‹จ์ˆœํ•œ ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ํ’๋ถ€ํ•œ ์ปจํ…์ธ ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ World Wide Web์„ ๋ฐœ๋ช…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


์ด ์•„์ด๋””์–ด๋Š” Netscape Navigator๋‚˜ Mosaic์ด๋ผ๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ํญ๋ฐœ์ ์ธ ์ธ๊ธฐ๋ฅผ ๋Œ๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.


๋ช‡ ๋…„ ํ›„, 1994๋…„์—๋Š” ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๊ธฐ ์œ„ํ•˜์—ฌ ์ฟ ํ‚ค๊ฐ€ ๋ฐœ๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์ฟ ํ‚ค๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ด์ „์— ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•œ ์ ์ด ์žˆ๋Š”์ง€, ์ „์ž ์ƒ๊ฑฐ๋ž˜ ์›น์‚ฌ์ดํŠธ๋ผ๋ฉด ์ด์ „์— ์‡ผํ•‘ํ•œ ํ•ญ๋ชฉ์€ ๋ฌด์—‡์ธ์ง€ ์ €์žฅํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ฟ ํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•œ Netscape๋Š” ์ด๋“ฌํ•ด ์›น ๋ธŒ๋ผ์šฐ์ €์— 2๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜์—ฌ ๋” ๋ฉ‹์ง„ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.


๋ฐ”๋กœ JavaScript์™€ DOM์ด๋ผ๊ณ  ํ•˜๋Š” HTML ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” API์ž…๋‹ˆ๋‹ค.


DOM ๋•๋ถ„์— JavaScript๋ฅผ ์ด์šฉํ•˜์—ฌ ํŽ˜์ด์ง€ URL, ์ฟ ํ‚ค, ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ด๋ฒคํŠธ๊นŒ์ง€ HTML ๋ฌธ์„œ์˜ ๋ชจ๋“  ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค!


HTML์ด ํ’๋ถ€ํ•ด์ง€๋ฉด์„œ ๋‹ค๋ฅธ ๋ฌธ์„œ๋‚˜ ๋ฏธ๋””์–ด ํ•ญ๋ชฉ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ๊ฒจ๋‚ฌ๊ณ , ์ด๋Ÿฌํ•œ ๋ฆฌ์†Œ์Šค์—๋Š” ์ž์ฒด ์ฟ ํ‚ค, DOM, JavaScript ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ฐ ๊ธฐํƒ€ ํ’๋ถ€ํ•œ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


๋ธŒ๋ผ์šฐ์ €์˜ ๋ฒ”์œ„ ๋‚ด์—์„œ ์ด๋Ÿฌํ•œ ์—”ํ‹ฐํ‹ฐ์™€ ์•ˆ์ „ํ•˜๊ฒŒ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฒจ๋‚œ ๊ฒƒ์ด SOP(Same-Origin Policy, ์ดํ•˜ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…) ์ž…๋‹ˆ๋‹ค.

๋™์ผ ์ถœ์ฒ˜โ€ฆ.์š”?

๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค!


์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ํ”„๋กœํ† ์ฝœ, ํ˜ธ์ŠคํŠธ, ํฌํŠธ, URL์ด ์ผ์น˜ํ•˜๋ฉด ๋™์ผํ•œ ์ถœ์ฒ˜๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ ํ™•์ธํ•ด๋ด…์‹œ๋‹ค!


http://example.com/script.js ์—์„œ ์ถœ๋ฐœํ•œ๋‹ค๋ฉดโ€ฆ

  • โœ…ย  http://example.com/api/
  • โ›”ย  http://example.org/api/
  • โ›”ย  http://api.example.org/
  • โ›”ย  http://example.com:8000/api/
  • โ›”ย  https://example.com/api/

๋งŒ์•ฝ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์—†์—ˆ๋‹ค๋ฉด?!

๋ณด์•ˆ์„ ์œ„ํ•ด ์ถ”๊ฐ€ํ•œ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ๋งŒ์•ฝ ์—†์—ˆ๋‹ค๋ฉด ์ €ํฌ์˜ ์ธํ„ฐ๋„ท ์„ธ์ƒ์€ ์–ด๋–ป๊ฒŒ ๋˜์—ˆ์„๊นŒ์š”?


์—ฌ๋Ÿฌ๋ถ„์ด ์–ด๋–ป๊ฒŒ๋“  ์†์•„์„œ www.your-bank.bad-site.com ์— ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ทธ ๋‚˜์œ ์‚ฌ์ดํŠธ์—๋Š” www.your-bank.com ์„ ๋กœ๋“œํ•˜๋Š” iframe์ด ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ์‚ฌ์ดํŠธ์—์„œ ํ•ฉ๋ฒ•์ ์œผ๋กœ ๋กœ๊ทธ์ธ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.


๋กœ๊ทธ์ธ ํ›„ ์•…์„ฑ ์‚ฌ์ดํŠธ์—์„  ๊ฐ„๋‹จํ•œ JavaScript ํ˜ธ์ถœ์„ ์ด์šฉํ•˜์—ฌ iframe์— ๋กœ๋“œ๋œ ๊ณ„์ขŒ ์ž”์•ก ๋ฐ์ดํ„ฐ DOM ์š”์†Œ์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

frames.bank_frame.document.getElementById('balance').value;

์—ฌ๋Ÿฌ๋ถ„์˜ ์˜์ง€์™€๋Š” ์ƒ๊ด€์—†์ด ์‚ฌ์ดํŠธ ๊ฐ„์˜ ์š”์ฒญ์ด ํ—ˆ๋ฝ๋˜์–ด ๊ณ„์ขŒ์— ์žˆ๋Š” ๋ˆ์„ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ์ธ์ถœํ•  ์ˆ˜๋„ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹คโ€ฆ!

์ด ์˜ˆ์‹œ๋ฅผ ์ „๋ฌธ ์šฉ์–ด๋กœ CSRF(Cross-Site Request Forgery, ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์š”์ฒญ ์œ„์กฐ)๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ XSS์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ๋œ ์„ธ์…˜์„ ์•…์šฉํ•˜์—ฌ ๊ณต๊ฒฉํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.


๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์€ ์ด CSRF ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๋ฐœ๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋‚˜์š”?

์ด์ „ ๊ธ€์—์„œ ๋ Œ๋”๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ™”๋ฉด ๊ทธ๋ฆฌ๋Š” ๊ณผ์ •์„ ์ง„ํ–‰ํ•œ๋‹ค๊ณ  ์ด์•ผ๊ธฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.


๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆœ ์žˆ์ง€๋งŒ Chrome์—์„œ๋Š” ๊ฐ ์‚ฌ์ดํŠธ ๋ณ„๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

Untitled

์‚ฌ์ดํŠธ ๊ฒฉ๋ฆฌ(site isolation)๋Š” 2018๋…„๋„์— ์ ์šฉ๋œ ๊ธฐ๋Šฅ์ด๋ฉฐ ๋น„๊ต์  ์ตœ์‹  ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.


๊ฐ ์‚ฌ์ดํŠธ๋ฅผ ์ž์ฒด ํ”„๋กœ์„ธ์Šค๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋‹ค๋ฅธ ์›น์‚ฌ์ดํŠธ์˜ ๊ณ„์ • ์ •๋ณด์— ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ ์ •๋ณด๋ฅผ ํ›”์น˜๋Š” ๊ฒƒ์„ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๊ทผ๋ฐ CORS๋Š”์š”?

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์€ ์›”๋“œ ์™€์ด๋“œ ์›น์˜ ์ดˆ์ฐฝ๊ธฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.


์˜ค๋Š˜๋‚  ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ์ธํ„ฐ๋„ท์€ ์ฝ˜ํ…์ธ , ์ฝ˜ํ…์ธ  ์ „์†ก ๋„คํŠธ์›Œํฌ, ๋‹จ์ผ ํŽ˜์ด์ง€ ๋””์ž์ธ, ์ข‹์•„์š” ๋ฐ ๊ณต์œ  ๋“ฑ์˜ ํ’๋ถ€ํ•œ ์ƒํƒœ๊ณ„๋กœ ํญ๋ฐœ์ ์œผ๋กœ ์„ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.


์ด ๋‹ค์–‘์„ฑ๊ณผ ๋ณ€ํ™”๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…๋„ ํ™•์žฅํ•˜๊ณ  ์ ์‘ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.


ํ•˜์ง€๋งŒ CORS๊ฐ€ ๋ฐ”๋กœ ๋“ฑ์žฅํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

XmlHTTPRequest

์›น์„ ๋” ํ’๋ถ€ํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด HTTP ํ†ต์‹ ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” API์ž…๋‹ˆ๋‹ค.
๋งค๋ฒˆ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ๋กœ๋“œํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก ๋ฆฌ์†Œ์Šค ๊ฐ„์˜ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.


ํ†ต์‹ ํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ์œ„ํ—˜์„ ๊ฐ์•ˆํ•  ๋•Œ XmlHTTPRequest๋Š” ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ… ๊ทœ์น™์„ ์—„๊ฒฉํ•˜๊ฒŒ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ์˜์—ญ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.


๊ทธ๋ ‡๊ธฐ์— XmlHTTPRequest์€ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์˜ ์š”๊ตฌ์‚ฌํ•ญ์ด ์™„์ „ํžˆ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


  • ๋‹ค๋ฅธ ์ถœ์ฒ˜ ์‚ฌ์ดํŠธ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜๋Š” ์žˆ์—ˆ์ง€๋งŒ, ์‘๋‹ต์„ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์š”์ฒญ URL์ด ๊ฐ™์€ ์ถœ์ฒ˜์— ์žˆ๋‹ค๋ฉด ์‘๋‹ต์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž ์ง€์ • ํ—ค๋”๋Š” ๊ฐ™์€ ์ถœ์ฒ˜์— ๋Œ€ํ•œ ์š”์ฒญ์—๋งŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JSONP

XmlHTTPRequest๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์ถœ์ฒ˜์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ์‘๋‹ต์„ ์ฝ์„ ์ˆœ ์—†์Šต๋‹ˆ๋‹ค.
๊ทธ๋ ‡๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์—์„œ ๋ฐ›์€ ํ™˜์œจ, ์ผ๊ธฐ ์˜ˆ๋ณด, ์•จ๋ฒ” ๋ชฉ๋ก ๋“ฑ์˜ ๊ธฐํƒ€ ์ •๋ณด๋Š” ์–ด๋–ป๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์—ˆ์„๊นŒ์š”?


๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์œผ๋กœ ์ธํ•ด ์ง์ ‘์ ์ธ HTTP ํ†ต์‹ ์„ ํ†ตํ•˜์—ฌ ์™ธ๋ถ€ ์ถœ์ฒ˜์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ HTML์˜ <script> ์š”์†Œ๋Š” ์™ธ๋ถ€ ์ถœ์ฒ˜๋กœ๋ถ€ํ„ฐ ์กฐํšŒ๋œ ๋‚ด์šฉ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด ์ฝ”๋“œ๋Š” ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์— ์–ด๊ธ‹๋‚˜์ง€๋งŒ,

var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://server.example.com/Users/1234', true);
xmlhttp.onload = function () {
  console.log('Retrieved Data: ' + xmlhttp.responseText);
};
xmlhttp.send(); // -> ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ ์ฐจ๋‹จ

์ด ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…๊ณผ๋Š” ๊ด€๊ณ„์—†์ด ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ JS ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

<script type="application/javascript" src="http://server.example.com/Users/1234"></script>

ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด { ... } ์ฒ˜๋Ÿผ JSON ๋ฌธ๋ฒ•์ด ๋‚˜์˜ฌ ๊ฒƒ์ด๊ณ , ์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์—์„œ ์ค‘๊ด„ํ˜ธ ๋ฌธ๋ฒ•์€ block์œผ๋กœ ํ•ด์„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


JSONP๋Š” ์ด๋Ÿฐ ์›น ๋ธŒ๋ผ์šฐ์ € ํŠน์„ฑ์„ ์ด์šฉํ•ด JSON ๋ฐ์ดํ„ฐ๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ง€์ •ํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์œ ํšจํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์œผ๋กœ ๊ฐ์‹ธ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์†กํ–ˆ์Šต๋‹ˆ๋‹ค.

// ์„œ๋ฒ„์—์„œ ๋ณด๋‚ด๋Š” ๊ฐ’
parseResponse({ Name: 'Foo', Id: 1234, Rank: 7 });

// ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ›๋Š” ๊ฐ’
<script
  type="application/javascript"
  src="http://server.example.com/Users/1234?callback=parseResponse"
></script>;

์ด๊ฒƒ ๋˜ํ•œ ๋ณด์•ˆ ์œ„ํ—˜์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
JSONP ์š”์ฒญ์ด ์‹คํ–‰๋˜๋ฉด JS๋Š” ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์—์„œ ๋ฐ˜ํ™˜๋œ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

CORS ๋“ฑ์žฅ!

JSONP๋ฅผ ์ด์šฉํ•˜๋ฉด ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์œผ๋กœ ์ธํ„ฐ๋„ท ์„ธ์ƒ์„ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“œ๋ ค๋Š” ๊ฐœ๋ฐœ์ž์™€ ๋ธŒ๋ผ์šฐ์ € ๊ณต๊ธ‰์—…์ฒด์˜ ์—ด๋ง์— ๋ถ€์‘ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.


๊ฐ€์žฅ ๋ณธ์งˆ์ ์ธ ์ด์œ ๋Š” JSONP๋กœ ๋งŒ๋“  ์™ธ๋ถ€ ์ถœ์ฒ˜์™€์˜ ํ†ต์‹ ์ด ๋‹จ๋ฐฉํ–ฅ์ด๋ฉฐ ์ฝ๊ธฐ ์ „์šฉ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


๊ณต๊ธ‰์—…์ฒด๋Š” ์ด๋Ÿฐ ์—ด๋ง์„ ๊ณ ๋ คํ•˜์—ฌ 2๊ฐ€์ง€ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.


Microsoft๋Š” ๊ณ ์œ ํ•œ ์•„์ด๋””์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๊ธฐ์— IE8~9์—์„  XDomainRequest๊ฐ€ ์†”๋ฃจ์…˜์ด ๋˜์—ˆ๊ณ , Chrome๊ณผ Firefox ๋“ฑ์˜ ๊ธฐํƒ€ ๋ธŒ๋ผ์šฐ์ €์—์„  CORS(Cross-Origin Resource Sharing)๋ผ๋Š” ๋Œ€์ฒด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

CORS

๋“œ๋””์–ด CORS์— ๋„์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค.


CORS๋Š” ์ถ”๊ฐ€ย HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ž…๋‹ˆ๋‹ค.


์ฆ‰, ๋ธŒ๋ผ์šฐ์ €์˜ ๊ตฌํ˜„ ์ŠคํŽ™์— ํฌํ•จ๋˜๋Š” ์ •์ฑ…์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


์„œ๋ฒ„๋Š” ํ‰์†Œ์ฒ˜๋Ÿผ ์š”์ฒญ์ด ์˜ค๋ฉด ์‘๋‹ต์„ ํ•ด์ค„ ๋ฟ์ด๊ณ ,ย ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž์‹ ์ด ๋ณด๋‚ธ ์š”์ฒญ ๋ฐ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์‘๋‹ต์˜ ๋ฐ์ดํ„ฐ๊ฐ€ CORS ์ •์ฑ…์„ ์ง€ํ‚ค๋Š”์ง€ ๊ฒ€์‚ฌํ•˜์—ฌ ์•ˆ์ „ํ•œ ์š”์ฒญ์„ ๋ณด๋‚ธ ๊ฑด์ง€ ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


๋”ฐ๋ผ์„œ ์„œ๋ฒ„๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต์„ ํ–ˆ๋”๋ผ๋„, ์•ˆ์ „ํ•œ ์š”์ฒญ์ด ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด ํ•ด๋‹น ์‘๋‹ต์„ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.


๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ ์—์„œ๋Š”ย ์ด๋Ÿฌํ•œ ์ •์ฑ…์ด ์ „ํ˜€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


CORS ์š”์ฒญ์€ ๋‹จ์ˆœ ์š”์ฒญ๊ณผ ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ+์‹ค์ œ ์š”์ฒญ์„ ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ƒํ™ฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋น„์ •ํ˜• ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์„œ๋ฒ„์— ๋Œ€ํ•ด ์ถ”๊ฐ€์ ์ธ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Untitled

๋‹จ์ˆœ ์š”์ฒญ์ธ ๊ฒฝ์šฐ

๋งŒ์•ฝ Origin์„ ํฌํ•จํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์š”์ฒญ์„ ๋ณด๋ƒˆ๋‹ค๋ฉด,

GET / HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,en-US;q=0.5
Origin: http://www.acceptmeplease.com
Connection: keep-alive

์„œ๋ฒ„์—์„œ ์˜ค๋Š” ์‘๋‹ต์€ Access-Control-Allow-Origin ๊ฐ’์„ ํฌํ•จํ•˜์—ฌ ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

HTTP/1.1 200 OK
Date: Sun, 24 Apr 2016 12:43:39 GMT
Server: Apache
Access-Control-Allow-Origin: http://www.acceptmeplease.com
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: application/xml
Content-Length: 423

<?xml version="1.0" encoding="UTF-8"?>
Untitled

์‚ฌ์ „ ์š”์ฒญ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ (ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ)

CORS ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋ธŒ๋ผ์šฐ์ €๋Š” OPTIONS ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™•์ธ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.


OPTIONS ๋ฉ”์„œ๋“œ๋กœ Access-Control-Request-Methodย ๋ฐย Access-Control-Request-Headers๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ถ”๊ฐ€ ํ—ค๋”๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


์ด๋Š” ์ถ”๊ฐ€ HTTP ํ—ค๋”๊ฐ€ ์ •์˜๋œ ์‹ค์ œ ์š”์ฒญ์—์„œ ๋ธŒ๋ผ์šฐ์ €์˜ ์˜๋„๋ฅผ ์•Œ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

OPTIONS /resources/post-here/ HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Connection: keep-alive
Origin: http://www.acceptmeplase.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-TOKEN-ID

OPTIONSย ์š”์ฒญ์„ ์ˆ˜๋ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.

HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache
Access-Control-Allow-Origin: http://www.acceptmeplease.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-TOKEN-ID
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

์‘๋‹ต ์ฝ”๋“œ๊ฐ€ 200์œผ๋กœ ๋ฐ˜ํ™˜์„ ํ•ด์•ผ ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์ด ํ—ˆ์šฉ๋œ ๊ฒƒ์œผ๋กœ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ํ†ตํ•ด ์•„๋ž˜ ํ—ค๋”๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • Access-Control-Allow-Origin: ์ž‘์„ฑ๋œ origin๊ณผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์™€์ผ๋“œ์นด๋“œ(*)๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋ชจ๋“  ๋„๋ฉ”์ธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • Access-Control-Allow-Methods: ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ๋•Œ ํ—ˆ์šฉ๋˜๋Š” HTTP ๋ฉ”์„œ๋“œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • Access-Control-Allow-Headers: ์‹ค์ œ ์š”์ฒญ ์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” HTTP ํ—ค๋” ๋ชฉ๋ก์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • Access-Control-Max-Age: ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ ์‹œ ์–ป์€ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๊ฐ„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ๋‹ค๋ฅด์ง€๋งŒ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ์˜ ์ด ๊ฐ’์€ ์ตœ๋Œ€ 10๋ถ„์ž…๋‹ˆ๋‹ค.

์ด์ œ ์‹ค์ œ ์š”์ฒญ์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.
ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์œผ๋กœ ์ธํ•ด Content-Type HTTP ํ—ค๋”์™€ X-Token-ID HTTP ํ—ค๋”๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

POST /resources/post-here/ HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Connection: keep-alive
X-Token-ID: aabbccddeeff0011223344556677889900
Content-Type: application/xml; charset=UTF-8
Content-Length: 55
Origin: http://www.acceptmeplease.com
Pragma: no-cache
Cache-Control: no-cache

<?xml version="1.0"?>
...
Untitled

์ถ”๊ฐ€๋กœ ์ฟ ํ‚ค ๊ฐ™์€ ์ธ์ฆ ๊ฐ’์„ ํฌํ•จํ•œ ์š”์ฒญ์ด๋ผ๋ฉดโ€ฆ

์ฟ ํ‚ค ๋“ฑ์˜ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ๋‹จ์—์„œ ์š”์ฒญ ์‹œ ๋ณ„๋„์˜ ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


Axios๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด withCredentials ์˜ต์…˜์„, fetch API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด credentials ์˜ต์…˜์„ ์„ค์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฐ ์„ค์ •์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ฟ ํ‚ค๋‚˜ Authorization ํ—ค๋”์— ์„ค์ •ํ•˜๋Š” ํ† ํฐ ๊ฐ’ ๋“ฑ์€ ์ ˆ๋Œ€๋กœ ์„œ๋ฒ„์—๊ฒŒ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


์œ„์™€ ๊ฐ™์€ ์„ค์ •์„ ํ†ตํ•ด ์ธ์ฆ ์ •๋ณด๋ฅผ ์š”์ฒญ์— ํฌํ•จ์‹œ์ผฐ๋‹ค๋ฉด, ์ด ์š”์ฒญ์€ ์ด์ œ ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ์ด ๋ฉ๋‹ˆ๋‹ค.
์„œ๋ฒ„๋Š” ์ด๋Ÿฌํ•œ ์š”์ฒญ์— ๋Œ€ํ•ด ์ผ๋ฐ˜์ ์ธ CORS ์š”์ฒญ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ๋Œ€์‘ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.


์‘๋‹ต์˜ย Access-Control-Allow-Originย ํ—ค๋”๊ฐ€ ์™€์ผ๋“œ์นด๋“œ(*)๊ฐ€ ์•„๋‹Œ ๋ถ„๋ช…ํ•œ Origin์œผ๋กœ ์„ค์ •๋˜์–ด์•ผ ํ•˜๊ณ ,ย Access-Control-Allow-Credentialsย ํ—ค๋”๋Š”ย true๋กœ ์„ค์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Untitled

CORS ๋™์ž‘๊ณผ์ • ์ •๋ฆฌ

Untitled

์ฐธ๊ณ  ์ž๋ฃŒ