CS Visualized: โœ‹๐Ÿผ๐Ÿ”ฅ CORS

Posted on September 03, 2020ย  - ย 7 min read

reference: https://dev.to/lydiahallie/cs-visualized-cors-5b8h

๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋“ค์ด ํ•œ ๋ฒˆ์ฏค์€ ์ฝ˜์†”์—์„œ ๋นจ๊ฐ„์ƒ‰ ์—๋Ÿฌ์ธ Access to fecthed has been blocked by CORS policy๋ฅผ ๋ณด๊ณ  ๋‹ต๋‹ตํ•จ์„ ๊ฐ€์กŒ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜ฌ ์ด ์—๋Ÿฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ ๊ทธ๋Ÿฐ ๊ธฐ๋ณธ์ ์ธ ๊ฒƒ๋“ค์„ ํ•˜๋Š” ๋Œ€์‹ , CORS๊ฐ€ ์‹ค์ œ๋กœ ํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ด๊ณ  ์‹ค์ œ๋กœ๋Š” ๊ทธ๊ฒƒ์ด ์™œ ์šฐ๋ฆฌ์—๊ฒŒ ๋„์›€์ด ๋˜๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ฃ  ๐Ÿ‘๐Ÿผ

โ—๏ธ ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” HTTP์˜ ๊ธฐ๋ณธ์— ๋Œ€ํ•ด์„œ๋Š” ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜น์‹œ ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด, ์ œ๊ฐ€ ์–ผ๋งˆ ์ „์— ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๋ฌผ์„ ๋ด์ฃผ์„ธ์š”. ๐Ÿ™‚ ์ด๋ฒˆ ์˜ˆ์‹œ๋Š” HTTP/2๊ฐ€ ์•„๋‹Œ HTTP/1.1๋กœ ์ž‘์„ฑ๋˜์—ˆ์ง€๋งŒ CORS์™€๋Š” ๋ฌด๊ด€ํ•ฉ๋‹ˆ๋‹ค.


ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” ์ข…์ข… ๋‹ค๋ฅธ ๊ณณ์— ์œ„์น˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•ด์•ผํ•  ๋•Œ๊ฐ€ ์žˆ์ฃ ! ์ด๋Ÿฐ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์ „์—, ๋ธŒ๋ผ์šฐ์ €๋Š” ๋จผ์ € ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์— ์š”์ฒญ์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค! ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋“ค์„ HTTP ์š”์ฒญ์— ์‹ค์–ด ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๐Ÿ™‚

api.website.com์ด ์œ„์น˜ํ•œ ์„œ๋ฒ„์—์„œ www.mywebsite.com ์›น ์‚ฌ์ดํŠธ์˜ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ฃ !

์™„๋ฒฝํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ˜ƒ ๋ฐฉ๊ธˆ HTTP ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ ๋’ค, ์šฐ๋ฆฌ ์š”์ฒญํ•œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์‘๋‹ต๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ •ํ™•ํžˆ ๋˜‘๊ฐ™์€ ์š”์ฒญ์„ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ์‹คํ–‰ํ•˜๋‹ค๊ณ  ํ•ด๋ณด์ฃ . www.mywebsite.com์—์„œ ์š”์ฒญ์„ ๋งŒ๋“œ๋Š” ๋Œ€์‹ , ์ด์ œ www.anotherdomain.com์—์„œ ์š”์ฒญ์„ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž ๊น, ๋ญ์ฃ ? ์šฐ๋ฆฐ ์™„์ „ํžˆ ๋™์ผํ•œ ์š”์ฒญ์„ ๋ณด๋ƒˆ๋Š”๋ฐ ์ด๋ฒˆ์—๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด์ƒํ•œ ์—๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ฃผ๋„ค์š”? ์šฐ๋ฆฐ ๋ฐฉ๊ธˆ CORS๋ฅผ ์‹ค์ œ๋กœ ๋ณธ ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ’ช๐Ÿผ ์ด์ œ ์™œ ์ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


โœ‹๐Ÿผ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same-Origin Policy)

์›น์€ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(same-origin policy)๋ผ๋Š” ๊ฒƒ์„ ์‹œํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ์š”์ฒญ๊ณผ ๋™์ผํ•œ ์ถœ์ฒ˜์— ์œ„์น˜ํ•œ ๋ฆฌ์†Œ์Šค๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ’ช๐Ÿผ

์˜ˆ๋ฅผ ๋“ค์–ด, https://mywebsite.com/image1.png์— ์œ„์น˜ํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋กœ๋“œํ•˜๋Š” ๊ฑด ๊ดœ์ฐฎ๋‹ค๋Š”๊ฑฐ์ฃ .

๋ฆฌ์†Œ์Šค๊ฐ€ ๋‹ค๋ฅธ (์„œ๋ธŒ)๋„๋ฉ”์ธ, ํ”„๋กœํ† ์ฝœ ๋˜๋Š” ํฌํŠธ์— ์œ„์น˜ํ•œ ๊ฒฝ์šฐ๋ฅผ ๊ต์ฐจ ์ถœ์ฒ˜(cross-origin)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

cors 3

๋ฉ‹์žˆ์–ด๋ณด์ด์ง€๋งŒ, ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์กด์žฌํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์—†๊ณ , ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์ด๋ชจ๊ฐ€ Facebook์—์„œ ๋ณด๋‚ธ ๋งŽ์€ ๋ฐ”์ด๋Ÿฌ์Šค ๋งํฌ ์ค‘ ํ•˜๋‚˜๋ฅผ ํด๋ฆญํ–ˆ๋‹ค๊ณ  ํ•ด๋ณด์ฃ . ์ด ๋งํฌ๋Š” ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์€ํ–‰ ์›น ์‚ฌ์ดํŠธ๊ฐ€ iframe์œผ๋กœ ๋กœ๋“œ๋˜๋Š” ์•…์˜์ ์ธ ์›น ์‚ฌ์ดํŠธ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•˜๊ฒŒ ๋˜๊ณ , ์ผ๋ถ€ ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋กœ๊ทธ์ธ์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๊ฒ ์ฃ ! ๐Ÿ˜ฌ

์ด๋Ÿฐ ์•…์˜์ ์ธ ์›น ์‚ฌ์ดํŠธ์˜ ๊ฐœ๋ฐœ์ž๋“ค์€ ์›น ์‚ฌ์ดํŠธ๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„๋“ค์„ ๋Œ€์‹ ํ•˜์—ฌ ์ž์‹ ์˜ ๊ณ„์ขŒ๋กœ ๋ˆ์„ ๋ณด๋‚ด๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด iframe์œผ๋กœ ์€ํ–‰ ์›น ์‚ฌ์ดํŠธ์˜ DOM ์ปจํ…์ธ ์™€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ• ๊ฑฐ์˜ˆ์š”!

๋„ค..์—„์ฒญ๋‚œ ๋ณด์•ˆ ๋ฆฌ์Šคํฌ์ฃ ! ์šฐ๋ฆฐ ๋ˆ„๊ตฌ๋„ ๋ชจ๋“  ๊ฒƒ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜์ง€ ์•Š์•„์š” ๐Ÿ˜ง

๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„, ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์šฐ๋ฆฌ๋ฅผ ๋„์™€์ค๋‹ˆ๋‹ค! ์ด ์ •์ฑ…์€ ๊ฐ™์€ ์ถœ์ฒ˜์—์„œ๋งŒ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” www.evilwebsite.com์ด๋ž€ ์ถœ์ฒ˜๊ฐ€ www.bank.com์˜ ๊ต์ฐจ ์ถœ์ฒ˜ ์ž์›์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค! ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์ด๋Ÿฐ ์š”์ฒญ์„ ๋ง‰์•„์ฃผ๊ณ  ์•…์˜์ ์ธ ์›น ์‚ฌ์ดํŠธ์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์šฐ๋ฆฌ์˜ ์€ํ–‰ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ๋ณด์žฅํ•ด์ค๋‹ˆ๋‹ค ๐Ÿฅณ

์ข‹์•„์š”, ๊ทผ๋ฐ ์ด๊ฒƒ์ด CORS์™€ ๋ฌด์Šจ ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š”๊ฑธ๊นŒ์š”?


๐Ÿ”ฅ ํด๋ผ์ด์–ธํŠธ ์˜์—ญ์˜ ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Client-side CORS)

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์‹ค์ œ๋กœ๋Š” ์Šคํฌ๋ฆฝํŠธ์—๋งŒ ์ ์šฉ๋˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด ์ •์ฑ…์„ JavaScript์˜ ์š”์ฒญ๊นŒ์ง€ โ€œํ™•์žฅโ€ํ•ฉ๋‹ˆ๋‹ค: ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์ผํ•œ ์ถœ์ฒ˜์—์„œ ๊ฐ€์ ธ์˜จ ๋ฆฌ์†Œ์Šค์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

ํ , ๊ทธ๋Ÿฐ๋ฐโ€ฆ์šฐ๋ฆฐ ์ข…์ข… ๊ต์ฐจ ์ถœ์ฒ˜์˜ ์ž์›๋“ค์— ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์ฃ  ๐Ÿค” ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ๋ฐฑ์—”๋“œ API์™€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค๋ฉด์š”? ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €๋Š” CORS๋ผ๊ณ  ํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค! ๐Ÿฅณ

CORS๋Š” ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Cross-Origin Resource Sharing)์˜ ์•ฝ์ž์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋™์ผํ•œ ์ถœ์ฒ˜์— ์œ„์น˜ํ•˜์ง€ ์•Š์€ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ์„ ํ—ˆ๋ฝํ•˜์ง€ ์•Š๋”๋ผ๋„, ์šฐ๋ฆฌ๋Š” CORS๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๋ณด์•ˆ์  ์ œ์•ฝ์„ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•˜์—ฌ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐ŸŽ‰

์‚ฌ์šฉ์ž ์—์ด์ „ํŠธ (์˜ˆ: ๋ธŒ๋ผ์šฐ์ €)๋Š” CORS ๋งค์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ HTTP ์‘๋‹ต์˜ ํŠน์ •ํ•œ CORS ๊ด€๋ จ ํ—ค๋” ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฐจ๋‹จ๋œ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! โœ…

๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์ด ์ด๋ฃจ์–ด์ง€๋ฉด, ํด๋ผ์ด์–ธํŠธ๋Š” ์ž๋™์ ์œผ๋กœ ์ถ”๊ฐ€ ํ—ค๋”๋ฅผ HTTP ์š”์ฒญ์— ๋ง๋ถ™์ž…๋‹ˆ๋‹ค: Origin์ด์ฃ . Origin ํ—ค๋”์˜ ๊ฐ’์€ ์š”์ฒญ์„ ์–ด๋””์—์„œ ํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ถœ์ฒ˜์ž…๋‹ˆ๋‹ค!

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ต์ฐจ ์ถœ์ฒ˜์˜ ์ž์›์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด, ์„œ๋ฒ„ ์‘๋‹ต์—์„œ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ํ—ˆ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํŠน์ • ํ—ค๋”๊ฐ€ ๋„˜์–ด์˜ค๊ธธ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค!


๐Ÿ’ป ์„œ๋ฒ„ ์˜์—ญ์˜ ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Server-side CORS)

์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž๋Š” Access-Control-* ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ๋“ค์„ HTTP ์‘๋‹ต์— ์ถ”๊ฐ€ ํ—ค๋”๋ฅผ ๋ง๋ถ™์—ฌ ์ฃผ์–ด ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ํ—ˆ๋ฝํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๐Ÿ”ฅ ์ด๋Ÿฌํ•œ CORS ์‘๋‹ต ํ—ค๋”์˜ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด์ œ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์— ์˜ํ•ด ์ฐจ๋‹จ๋œ ๊ต์ฐจ ์ถœ์ฒ˜ ์‘๋‹ต ์ค‘ ํŠน์ •ํ•œ ๊ฒƒ๋“ค์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค!

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€์˜ CORS ํ—ค๋”๋“ค์ด ์žˆ์ง€๋งŒ, ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค์˜ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ธŒ๋ผ์šฐ์ €์— ํ•„์š”ํ•œ ํ—ค๋”๊ฐ€ ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค: Access-Control-Allow-Origin์ด์ฃ ! ๐Ÿ™‚ ์ด ํ—ค๋”์˜ ๊ฐ’์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญํ•œ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ถœ์ฒ˜๋ฅผ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์„œ๋ฒ„๊ฐ€ https://mywebsite.com์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒฝ์šฐ, Access-Control-Allow-Origin ํ—ค๋”์˜ ๊ฐ’์„ ํ•ด๋‹น ๋„๋ฉ”์ธ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

๋†€๋ž๋„ค์š”! ๐ŸŽ‰ ์ด ํ—ค๋”๋Š” ์ด์ œ ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋กœ ๋Œ๋ ค์ฃผ๋Š” ์‘๋‹ต์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ํ—ค๋”๊ฐ€ ๋”ํ•ด์ง์œผ๋กœ์จ, ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ https://mywebsite.com์—์„œ https://api.mywebsite.com ์— ์œ„์น˜ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ณ  ๋ฐ›๋Š”๋ฐ ๋” ์ด์ƒ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์ œํ•œ์„ ๊ฑธ์ง€ ์•Š์Šต๋‹ˆ๋‹ค!

๋ธŒ๋ผ์šฐ์ € ๋‚ด์˜ CORS ๋งค์ปค๋‹ˆ์ฆ˜์€ Access-Control-Allow-Originํ—ค๋”์˜ ๊ฐ’์ด ์š”์ฒญ์— ์˜ํ•ด ๋ณด๋‚ด์ง„ Origin์˜ ๊ฐ’๊ณผ ๊ฐ™์€์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด์ฃ . ๐Ÿคš๐Ÿผ

์ด๋ฒˆ ๊ฒฝ์šฐ, ์š”์ฒญ์˜ ์ถœ์ฒ˜๋Š” https://www.mywebsite.com ์ด๊ณ , ์ด๊ฑด Access-Control-Allow-Origin ์‘๋‹ต ํ—ค๋”์˜ ๋ชฉ๋ก์— ์†ํ•ด์žˆ์ฃ !

์™„๋ฒฝํ•˜๋„ค์š”! ๐ŸŽ‰ ์šฐ๋ฆฐ ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์–ด์š”! ๊ทธ๋Ÿผ Access-Control-Allow-Origin ํ—ค๋”์˜ ๋ชฉ๋ก์— ์†ํ•˜์ง€ ์•Š์€ ์ถœ์ฒ˜์˜ ์ž์›์— ์ ‘๊ทผํ•˜๋ ค ํ•œ๋‹ค๋ฉด ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚ ๊นŒ์š”? ๐Ÿค”

์•„์•„ ๋„ค, CORS๋Š” ๋•Œ๋•Œ๋กœ ์šฐ๋ฆฌ๋ฅผ ๋‹ต๋‹ตํ•˜๊ฒŒ ํ•˜๋Š” ์ด ์•…๋ช… ๋†’์€ ์—๋Ÿฌ๋ฅผ ๋˜์ง€์ฃ ! ํ•˜์ง€๋งŒ ์ด์ œ ์šฐ๋ฆฐ ์ด๊ฑธ ์™„์ „ํžˆ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์ฃ .

The 'Access-Control-Allow-Origin' header has a value
 'https://www.mywebsite.com' that is not equal 
to the supplied origin.

์ด๋ฒˆ ๊ฒฝ์šฐ, ์ œ๊ณต๋œ ์ถœ์ฒ˜๋Š” https://www.anotherwebsite.com์ด์ฃ . ํ•˜์ง€๋งŒ ์„œ๋ฒ„๋Š” Access-Control-Allow-Origin ํ—ค๋” ๋‚ด ํ—ˆ์šฉ๋œ ์ถœ์ฒ˜์˜ ๋ชฉ๋ก์— ์ด ์ถœ์ฒ˜๊ฐ€ ์—†์ฃ ! CORS๋Š” ์ด ์š”์ฒญ์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ฐจ๋‹จํ•˜๊ณ , ์ฝ”๋“œ ๋‚ด์—์„œ๋„ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜์ฃ  ๐Ÿ˜ƒ

CORS ๋˜ํ•œ ํ—ˆ์šฉ๋œ ์ถœ์ฒ˜์˜ ๊ฐ’์œผ๋กœ *์ธ ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๋ง์€ ๋ชจ๋“  ์ถœ์ฒ˜์—์„œ ์š”์ฒญํ•œ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ˆ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!


Access-Control-Allow-Origin์€ ์šฐ๋ฆฌ๊ฐ€ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ CORS ํ—ค๋” ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž๋Š” ์„œ๋ฒ„์˜ ํŠน์ • ์š”์ฒญ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด COS ์ •์ฑ…์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ’ช๐Ÿผ

๋ณดํ†ต ์‚ฌ์šฉ๋˜๋Š” ๋˜ ๋‹ค๋ฅธ ํ—ค๋”๋Š” Access-Control-Allow-Methods ํ—ค๋”์ž…๋‹ˆ๋‹ค! CORS๋Š” ์ง€์ •๋œ ๋ฉ”์„œ๋“œ๋กœ ์ „์†ก์ด๋œ ๊ฒฝ์šฐ์—๋งŒ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋  ๊ฒ๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š”, GET, POST ๋˜๋Š” PUT ๋ฉ”์„œ๋“œ๋กœ ์˜ค๋Š” ์š”์ฒญ๋งŒ ํ—ˆ๋ฝ๋ฉ๋‹ˆ๋‹ค! ๋‹ค๋ฅธ PATCH๋‚˜ DELETE๊ฐ™์€ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋“ค์€ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค โŒ

๋งŒ์•ฝ ๋‹ค๋ฅธ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ CORS ํ—ค๋”๋“ค์ด ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•˜๊ณ , ์–ด๋””์— ์‚ฌ์šฉ๋˜๋Š”์ง€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด, ์ด ๋ชฉ๋ก์„ ํ™•์ธํ•ด๋ณด์„ธ์š”.

PUT, PATCH ๋ฐ DELETE ์š”์ฒญ์— ๋Œ€ํ•ด CORS๋Š” ์‹ค์ œ๋กœ ์ด ์š”์ฒญ๋“ค์„ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ™ƒ ์ด๋Ÿฐ โ€๋‹จ์ˆœํ•˜์ง€ ์•Š์€โ€ ์š”์ฒญ์€ ์‚ฌ์ „ ์š”์ฒญ(preflight request)๋ผ๊ณ  ๋ถ€๋ฅผ๊ป˜์š”!


๐Ÿš€ ์‚ฌ์ „ ์š”์ฒญ(Preflighted Requests)

CORS๋Š” ์š”์ฒญ์„ ๋‘ ๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค: ๋‹จ์ˆœ ์š”์ฒญ๊ณผ ์‚ฌ์ „ ์š”์ฒญ์ด์ฃ . ๋‹จ์ˆœํ•œ์ง€ ์ „์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋Š” ์š”์ฒญ ๋‚ด์˜ ์ผ๋ถ€ ๊ฐ’์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค(๊ฑฑ์ • ๋ง์•„์š”. ์ด๊ฒƒ๋“ค์„ ๊ธฐ์–ตํ•  ํ•„์š”๋Š” ์—†์–ด์š”).

์š”์ฒญ์ด GET ๋˜๋Š” POST ๋ฉ”์„œ๋“œ๊ณ  ์‚ฌ์šฉ์ž ์ง€์ • ํ—ค๋”๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์ด ์š”์ฒญ์€ ๋‹จ์ˆœ ์š”์ฒญ์ž…๋‹ˆ๋‹ค! PUT, PATCH ๋˜๋Š” DELETE ๋ฉ”์„œ๋“œ๋กœ ์ด๋ค„์ง„ ์š”์ฒญ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์ „์ฒ˜๋ฆฌ ๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋‹จ์ˆœ ์š”์ฒญ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ถฉ์กฑ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด MDN์— ์œ ์šฉํ•œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค!

๊ทธ๋Ÿฐ๋ฐ โ€œ์‚ฌ์ „ ์š”์ฒญโ€์ด๋ž€ ๋ฌด์—‡์ด๊ณ , ์™œ ์ด๋Ÿฐ ๊ฒŒ ์ƒ๊ฒผ์„๊นŒ์š”?


์‹ค์ œ ์š”์ฒญ์ด ์ „์†ก๋˜๊ธฐ ์ „์—, ํด๋ผ์ด์–ธํŠธ๋Š” ์‚ฌ์ „ ์š”์ฒญ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค! ์‚ฌ์ „ ์š”์ฒญ์—๋Š” Access-Control-Request-* ํ—ค๋”์— ์‹ค์ œ ์š”์ฒญ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ”ฅ

์ด๊ฒƒ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•˜๊ณ ์ž ํ•˜๋Š” ์‹ค์ œ ์š”์ฒญ์— ๋Œ€ํ•œ ์„œ๋ฒ„์˜ ์ •๋ณด๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค: ์š”์ฒญ์˜ ๋ฉ”์„œ๋“œ, ์ถ”๊ฐ€์ ์ธ ํ—ค๋”๋“ค ๊ทธ๋ฆฌ๊ณ  ๊ธฐํƒ€.

์„œ๋ฒ„๋Š” ์ด ์‚ฌ์ „ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๊ณ  ๋นˆ HTTP ์‘๋‹ต์„ ์„œ๋ฒ„์˜ CORS ํ—ค๋”๋“ค์„ ์‹ค์–ด ๋ณด๋ƒ…๋‹ˆ๋‹ค! ๋ธŒ๋ผ์šฐ์ €๋Š” ๋นˆ ๋ฐ์ดํ„ฐ์™€ CORS ํ—ค๋”๋“ค์ด ์žˆ๋Š” ์‚ฌ์ „ ์‘๋‹ต์„ ์ˆ˜์‹ ํ•˜๊ณ  ํ—ˆ์šฉ๋˜๋Š” HTTP ์š”์ฒญ์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค! โœ…

์ด ๊ฒฝ์šฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ์‹ค์ œ ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๊ณ , ์š”์ฒญํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ์‘๋‹ต์„ ์ˆ˜์‹ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค!

ํ•˜์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ CORS๋Š” ์‚ฌ์ „ ์š”์ฒญ์„ ์ฐจ๋‹จํ•˜๊ณ , ์‹ค์ œ ์š”์ฒญ์€ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. โœ‹๐Ÿผ ์‚ฌ์ „ ์š”์ฒญ์€ CORS ์ •์ฑ…์ด (์•„์ง) ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ์„œ๋ฒ„์˜ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค! ์„œ๋ฒ„๋Š” ์ด์ œ ์ž ์žฌ์ ์œผ๋กœ ์›ํ•˜์ง€ ์•Š๋Š” ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ๋ฉ๋‹ˆ๋‹ค ๐Ÿ˜ƒ

๐Ÿ’ก ์„œ๋ฒ„์™€์˜ ์™•๋ณต ํšŸ์ˆ˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด CORS ์š”์ฒญ์— Access-Control-Max-Age ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์‚ฌ์ „ ์‘๋‹ต์„ ์บ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์‚ฌ์ „ ์‘๋‹ต์„ ์ด๋Ÿฐ์‹์œผ๋กœ ์บ์‹œํ•˜๊ฒŒ ๋˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ƒˆ๋กœ์šด ์‚ฌ์ „ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋Œ€์‹  ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค!


๐Ÿชย ์ž๊ฒฉ ์ฆ๋ช…(Credentials)

์ฟ ํ‚ค, ์ธ์ฆ ํ—ค๋” ๋ฐ TLS ์ธ์ฆ์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์ผ ์ถœ์ฒ˜ ์š”์ฒญ์—์„œ๋งŒ ์„ค์ •์ด ๋ฉ๋‹ˆ๋‹ค! ํ•˜์ง€๋งŒ, ์ด๋Ÿฌํ•œ ์ž๊ฒฉ ์ฆ๋ช…๋“ค์„ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์—์„œ๋„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์ฃ . ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์ฟ ํ‚ค๋ฅผ ์š”์ฒญ์— ํฌํ•จ์‹œํ‚ค๊ณ  ์‹ถ์„ ์ˆ˜๊ฐ€ ์žˆ์–ด์š”!

CORS๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž๊ฒฉ ์ฆ๋ช…์„ ํฌํ•จํ•˜์ง€ ์•Š์ง€๋งŒ, ์šฐ๋ฆฐ Access-Control-Allow-Credentials CORS ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ด๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰

๋งŒ์•ฝ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์— ์ฟ ํ‚ค ๋ฐ ๋‹ค๋ฅธ ๊ถŒํ•œ ํ—ค๋”๋ฅผ ํฌํ•จํ•˜๋ ค๋ฉด, ์š”์ฒญ์—์„œ withCredentials ํ•„๋“œ์— true๋ฅผ ํ• ๋‹นํ•˜๊ณ  Access-Control-Allow-Credentials ํ—ค๋”๋ฅผ ์‘๋‹ต์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„ค์ •์ด ๋‹ค ๋์Šต๋‹ˆ๋‹ค! ์ด์ œ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์— ์ž๊ฒฉ ์ฆ๋ช…์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿฅณ


CORS ์—๋Ÿฌ๊ฐ€ ๋•Œ๋•Œ๋กœ ๋‹ต๋‹ตํ•˜๋‹ค๋Š”๋ฐ ๋ชจ๋‘ ๋™์˜ ํ• ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋”ฐ๋Š” ๊ฒƒ์€ ๋†€๋ผ์šด ์ผ์ž…๋‹ˆ๋‹ค (๋ถ„๋ช… ์‚ฌ๋ž‘์„ ๋ฐ›์•„์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ์ด์˜ˆ์š”) โœจ

๋‹น์—ฐํžˆ ์ด ํฌ์ŠคํŠธ์—์„œ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…๊ณผ CORS๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„, ์ด๊ฒƒ๋“ค์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ •๋ณด๋“ค์ด ์—ฌ๊ธฐ๋‚˜ W3 ์ŠคํŽ™์— ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ’ช๐Ÿผ

๋Š˜ ๊ทธ๋ ‡๋“ฏ, ์งˆ๋ฌธ์€ ํ™˜์˜์ž…๋‹ˆ๋‹ค! ๐Ÿ˜Š