TIL98. HTTP : CORS ๋ž€?

ID์งฑ์žฌยท2021๋…„ 12์›” 6์ผ
0

HTTP

๋ชฉ๋ก ๋ณด๊ธฐ
13/17
post-thumbnail

๐ŸŒˆ CORS ๋ž€?

๐Ÿ”ฅ Origin(์ถœ์ฒ˜) ๋ž€?

๐Ÿ”ฅ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(SOP)

๐Ÿ”ฅ ๊ต์ฐจ ์ถœ์ฒ˜ ์ž์› ๊ณต์œ (CORS)

๐Ÿ”ฅ CORS ์‹œ๋‚˜๋ฆฌ์˜ค



1. Origin(์ถœ์ฒ˜) ๋ž€?

๐Ÿค” ๊ฐ™์€ ์ถœ์ฒ˜๋ž€ ๋ฌด์—‡์ผ๊นŒ?

โœ”๏ธ ๊ฐ™์€ ์ถœ์ฒ˜(same origin)์€ ํ”„๋กœํ† ์ฝœ, ํ˜ธ์ŠคํŠธ, ํฌํŠธ๊ฐ€ ์ผ์น˜ํ•  ๋•Œ๋Š” ์˜๋ฏธํ•˜๊ณ  ์ด ํŒ๋‹จ์€ ํด๋ผ์ด์–ธํŠธ๋‚˜ ์„œ๋ฒ„๊ฐ€ ์•„๋‹Œ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŒ๋‹จํ•œ๋‹ค.

โœ”๏ธ RFC ํ‘œ์ค€์—์„œ HTTPS๋‚˜ HTTP ํ”„๋กœํ† ์ฝœ์—์„œ๋Š” ํฌํŠธ ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ด ๋˜ํ•œ ๋ถˆ์ผ์น˜ํ•˜๋ฉด ๊ฐ™์€ ์ถœ์ฒ˜๋กœ ์ธ์ •๋˜์ง€ ์•Š๋Š”๋‹ค.

โœ”๏ธ ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ 1๋ฒˆ์€ ๊ฐ™์€ origin์ด์ง€๋งŒ, 2๋ฒˆ์€ ๋‹ค๋ฅธ origin์ด๋‹ค. ํ”„๋กœํ† ์ฝœ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

1. "https://jaewon.com/products" == "https://jaewon.com/rooms/1"
2. "https://jaewon.com/products" != "http://jaewon.com/products"

โœ”๏ธ ํ•ด๋‹น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ origin์€ ๋ธŒ๋ผ์šฐ์ € console์ฐฝ์— ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

$ console.log(location.origin)

๐Ÿค” ๊ฐ™์€ ์ถœ์ฒ˜๋ฅผ ์–ด๋–ป๊ฒŒ ํ™•์ธํ• ๊นŒ?

โœ”๏ธ ํด๋ผ์ด์–ธํŠธ์—์„œ request๋ฅผ ๋ณด๋‚ด๋ฉด, header์— origin์— ์ถœ์ฒ˜๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„์—์„œ response๋ฅผ ์ค„ ๋•Œ, Access-Control-Allow-Origin๋ผ๋Š” header์˜ ํ•„๋“œ๊ฐ’์— origin์„ ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค.

โœ”๏ธ ์ด ๋•Œ, request์˜ origin ๊ฐ’๊ณผ response์˜ Access-Control-Allow-Origin์˜ ๊ฐ’์ด ์ผ์น˜ํ•˜๋ฉด ๊ฐ™์€ ์ถœ์ฒ˜๋ผ๊ณ  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋‹ค.



2. ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(SOP)

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

โœ”๏ธ SOP๋Š” ์–ด๋–ค ์ถœ์ฒ˜(origin)์—์„œ ๋ถˆ๋Ÿฌ์˜จ ๋ฌธ์„œ๋‚˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๊ฐ€์ ธ์˜จ ๋ฆฌ์†Œ์Šค์™€ ์ƒํ˜ธ์ž‘์šฉ ํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๋Š” ์ค‘์š”ํ•œ ๋ณด์•ˆ ๋ฐฉ์‹์ด๋‹ค.

โœ”๏ธ ์ฆ‰, SOP๋Š” ๋™์ผํ•œ ์ถœ์ฒ˜์˜ origin๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๋Š” ๋ณด์•ˆ ์ •์ฑ…์œผ๋กœ ์ด ์ •์ฑ…์„ ์ง€ํ‚ค๋ฉด XSS๋‚˜ XSRF ๋“ฑ์˜ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ๋ฐฉ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

  • XSS(Cross Site Scription, ์‚ฌ์ดํŠธ ๊ฐ„ ์Šคํฌ๋ฆฝํŒ…) : ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ๊ถŒํ•œ์ด ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์›น ์‚ฌ์ดํŠธ์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ณต๊ฒฉ ํ–‰์œ„
  • XSRF(Cross Site Request Forgery, ์‚ฌ์ดํŠธ ๊ฐ„ ์š”์ฒญ ์œ„์กฐ) : ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ์˜์ง€์™€๋Š” ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ณต๊ฒฉ์ž๊ฐ€ ์ด๋„ํ•œ ํ–‰์œ„(์ˆ˜์ •, ์‚ญ์ œ, ๋“ฑ๋ก ๋“ฑ)๋ฅผ ์›น์‚ฌ์ดํŠธ์— ์š”์ฒญํ•˜๊ฒŒํ•˜๋Š” ๊ณต๊ฒฉ ํ–‰์œ„

โœ”๏ธ ๋‹จ, SOP ๋•Œ๋ฌธ์— ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ๋ชปํ•˜๋Š” ๋ถˆํŽธ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด์— ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด JONP, Reverse Proxy, Flash Socker ๋“ฑ ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค์—ˆ์ง€๋งŒ Cross Domain ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํ‘œ์ค€์˜ ํ•„์š”์„ฑ์ด ์ปค์ง€๊ฒŒ ๋˜์—ˆ๋‹ค.

โœ”๏ธ ์ด์— W3C์˜ ๊ถŒ์žฅ์‚ฌํ•ญ์œผ๋กœ CORS ์ •์ฑ…์„ ๋ฐœํ‘œํ•˜๊ฒŒ ๋œ๋‹ค.



3. ๊ต์ฐจ ์ถœ์ฒ˜ ์ž์› ๊ณต์œ (CORS)

๐Ÿค” Cross-Origin Resource Sharing

โœ”๏ธ CORS๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์™ธ๋ถ€ ๋„๋ฉ”์ธ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์‹์„ ํ‘œ์ค€ํ™”ํ•œ ์ •์ฑ…์ด๋‹ค.

โœ”๏ธ ์ด ์ •์ฑ…์— ์˜๊ฑฐํ•ด์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ •ํ•ด์ง„ ํ—ค๋”๋ฅผ ํ†ตํ•ด ์„œ๋กœ ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์— ๋ฐ˜์‘ํ• ์ง€, ์›น๋ธŒ๋ผ์šฐ์ €์— ์˜ํ•ด ํ‰๊ฐ€๋˜๊ณ  ๊ฒฐ์ •๋œ๋‹ค.

โœ”๏ธ ์ฆ‰, ๊ฐ™์€ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹ˆ๋”๋ผ๋„, CORS ์ •์ฑ…์— ์˜ํ•ด ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.



2. CORS ์‹œ๋‚˜๋ฆฌ์˜ค

๐Ÿค” Preflight Request

โœ”๏ธ Preflight Request๋Š” ๋ณธ ์š”์ฒญ ์ด์ „์— ์ด๋ค„์ง€๋Š” ์˜ˆ๋น„ ์š”์ฒญ ๊ฐœ๋…์ด๋‹ค. ์ด ์‚ฌ์ „ ์š”์ฒญ์€ OPTIONS๋ผ๋Š” ๋งค์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ด๋ค„์ง„๋‹ค.

โœ”๏ธ ์ด ์˜ˆ๋น„ ์š”์ฒญ์—์„œ request์˜ origin๊ฐ’๊ณผ response์˜ Access-Control-Allow-Origin์ด ์ผ์น˜ํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ๊ฐ™์€ ์ถœ์ฒ˜๋ผ ์ธ์‹ํ•ด์„œ ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค.

โœ”๏ธ ์ด์— ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฐ™์€ ์ถœ์ฒ˜๋ผ ์ธ์‹ํ•˜๊ฒŒ ๋˜๋ฉด CORS ์ •์ฑ…์— ์œ„๋ฐ˜๋˜์ง€ ์•Š์•˜๋‹ค ํŒ๋‹จํ•˜๊ณ , ๋ณธ ์š”์ฒญ์— ์ œ๋Œ€๋กœ๋œ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

โœ”๏ธ ๋งŒ์ผ ์˜ˆ๋น„ ์š”์ฒญ์—์„œ origin๊ฐ’๊ณผ Access-Control-Allow-Origin๊ฐ’์ด ๋ถˆ์ผ์น˜ํ•˜๋‹ค๋ฉด ๋ณธ ์š”์ฒญ์€ ์ด๋ค„์ง€์ง€ ์•Š๋Š”๋‹ค.

๐Ÿค” Simple Request

โœ”๏ธ Simple Request๋Š” Preflight Request ์š”์ฒญ์ด ๋ณ„๋„๋กœ ์กด์žฌํ•˜์ง€ ์•Š๊ณ , Simple Request ๋•Œ ๋ชจ๋‘ ํฌํ•จ๋˜์–ด์žˆ๋Š” ๊ฐœ๋…์ด๋‹ค.

โœ”๏ธ ์ด ๋˜ํ•œ origin๊ณผ Access-Control-Allow-Origin์„ ๋น„๊ตํ•ด์„œ ๋™์ผ ์ถœ์ฒ˜์ธ์ง€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ํŒ๋‹จ๋˜๊ณ  ๋™์ผํ•  ๊ฒฝ์šฐ, ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

โœ”๏ธ ๋‹จ, Simple Request๋Š” HEAD, GET, POST ์ค‘ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ ์ผ ๋•Œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ณ , ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” header์˜ ์ข…๋ฅ˜๊ฐ€ ์ œํ•œ์ ์ด๋‹ค. ํŠนํžˆ, Content-Type์œผ๋กœ application/json์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

๐Ÿค” Credentialed Request

โœ”๏ธ Credentialed Request๋Š” ๋ณด๋‹ค ๋ณด์•ˆ์„ ๊ฐ•ํ™”์‹œํ‚จ ๋ฐฉ์‹์œผ๋กœ ์ฟ ๊ธฐ๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•ด ์˜ต์…˜์ด๋‹ค. ์ด ์˜ต์…˜์œผ๋กœ same-origin(๊ธฐ๋ณธ๊ฐ’), include, omit์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

โœ”๏ธ same-origin์€ ๊ฐ™์€ ์ถœ์ฒ˜ ๊ฐ„ ์š”์ฒญ์—๋งŒ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด๊ฒ ๋‹ค๋Š” ์˜ต์…˜ ๊ฐ’์ด๊ณ , include๋Š” ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. omit์€ ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์ง€ ์•Š์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

โœ”๏ธ ์ฐธ๊ณ ๋กœ ์œ„ ์˜ต์…˜๊ฐ’๋“ค์€ fetch๋ฅผ ์ค„ ๋•Œ, ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์ด๋‹ค.

fetch('https://jaewon.com/products/1', { credentials: 'include'})

โœ”๏ธ ๋‹จ, Access-Control-Allow-Origin์— *์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , ๋ช…์‹œ์ ์ธ URL์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. ๋˜ํ•œ ์‘๋‹ต header์— Access-Control-Allow-Credentails:true๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค.

profile
Keep Going, Keep Coding!

0๊ฐœ์˜ ๋Œ“๊ธ€