CORS

๊ฐ•์€๋น„ยท2021๋…„ 11์›” 3์ผ
2

Network

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

๐Ÿคž CORS๋ž€?

Cross-Origin Resource Sharing

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


same origin ๐Ÿ†š cross origin

โœ” Origin์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•

  1. Schema
  2. Host
  3. Port
  • https://wonit.tistory:80/post
  • https://wonit.tistory:80/post/id?page=10
  • https://wonit.tistory:80/main/post/comment
    -> Origin์ด ๋™์ผํ•œ ์ƒํƒœ

โœจ SOP

Same Origin Policy

  • 2011๋…„ RFC 6454์—์„œ ๋“ฑ์žฅํ•œ ๋ณด์•ˆ ์ •์ฑ…์œผ๋กœ ๋™์ผํ•œ ์ถœ์ฒ˜์˜ Origin๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ •์ฑ…์ด๋‹ค.
  • ํ•˜์ง€๋งŒ, CORS ์ •์ฑ…์„ ์ง€ํ‚จ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์€ origin์ด ๋‹ค๋ฅด๋”๋ผ๋„ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค.

๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ๋Š” CORS์™€ SOP ์ •์ฑ… ๋•Œ๋ฌธ์— ์‹ ๊ฒฝ์จ์•ผ ํ•˜๋Š” ๊ฒƒ๋“ค์ด ๋Š˜์–ด๋‚˜์„œ ๊ท€์ฐฎ์„ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Ÿฌํ•œ ์ •์ฑ…์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— CSRF๋‚˜ XSS์™€ ๊ฐ™์€ ๋ณด์•ˆ์ƒ์˜ issue๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ‘€ CORS ๋™์ž‘ ๋ฐฉ๋ฒ•

Cross Origin์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ๋Š” request header์˜ Origin ํ•„๋“œ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ถœ์ฒ˜๋ฅผ ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.
  2. ์ดํ›„ ์„œ๋ฒ„๋Š” Access-Control-Allow-Origin ํ—ค๋”์— ํ—ˆ์šฉ๋œ Origin์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค.
  3. ์‘๋‹ต์„ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ๋Š” ์ž์‹ ์ด ๋ณด๋ƒˆ๋˜ ์š”์ฒญ์˜ Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ธ ์‘๋‹ต์˜ Access-Control-Allow-Origin ๊ฐ’์„ ๋น„๊ตํ•ด ์œ ํšจํ•œ ์‘๋‹ต์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๊ฒฐ์กํ•œ๋‹ค.

Access-Control-Allow-Origin

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

๊ธฐ๋ณธ์ ์ธ ํ๋ฆ„์€ ๊ฐ„๋‹จํ•˜์ง€๋งŒ, CORS๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์žˆ๋‹ค.

1. Preflight Request

์š”์ฒญ์„ ํ•œ ๋ฒˆ์— ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์˜ˆ๋น„ ์š”์ฒญ๊ณผ ๋ณธ ์š”์ฒญ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  1. ๋จผ์ €, OPTIONS ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค. ์ด๋•Œ Origin์— ๋Œ€ํ•œ ์ •๋ณด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ณธ ์š”์ฒญ์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ •๋ณด๋“ค๋„ ํ•จ๊ป˜ ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค. (Http Method, Content-Type ๋“ฑ๋“ฑ)
  2. ์ดํ›„ ์„œ๋ฒ„๋Š” Access-Control-Allow-Origin ํ—ค๋”์— ํ—ˆ์šฉ๋œ Origin์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด์•„ ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค.
  3. ํด๋ผ์ด์–ธํŠธ ์ธก์€ ์ž์‹ ์ด ๋ณด๋ƒˆ๋˜ ์š”์ฒญ์˜ Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ธ ์‘๋‹ต์˜ Access-Control-Allow-Origin ๊ฐ’์„ ๋น„๊ตํ•ด ์œ ํšจํ•œ ์‘๋‹ต์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๊ฒฐ์กํ•œ๋‹ค.
  4. ๋งŒ์•ฝ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ๋‹ค๋ฅด๋ฉด CORS ์ •์ฑ… ์œ„๋ฐ˜์ด๋‹ค. ๐Ÿšจ

2. Simple Request

Preflight Request์—์„œ๋Š” ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๊ทธ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ํ†ตํ•ด CORS ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ–ˆ๋‹ค๋ฉด, Simple Request๋Š” ์˜ˆ๋น„ ์š”์ฒญ ์—†์ด ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๊ทธ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ํ†ตํ•ด CORS ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค.

์ „๋ฐ˜์ ์ธ CORS ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€ ํŒ๋‹จ ๋กœ์ง์€ ๋น„์Šทํ•˜๊ณ , ์˜ˆ๋น„ ์š”์ฒญ์˜ ์กด์žฌ ์œ ๋ฌด๋งŒ ๋‹ค๋ฅด๋‹ค.

Simple Request๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด์ด ์กด์žฌํ•œ๋‹ค.

  1. ์š”์ฒญ ๋ฉ”์„œ๋“œ๋Š” GET, HEAD, POST ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.
  2. Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width๋ฅผ ์ œ์™ธํ•œ ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
  3. ๋งŒ์•ฝ Content-Type๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— application/x-www-form-urlencoded, multipart/form-data, text/plain๋งŒ ํ—ˆ์šฉ๋œ๋‹ค.

์ด๋Ÿฌํ•œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ Simple Request๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ๋ฐฉ์‹์„ ์ด์šฉํ•˜์—ฌ ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ด CORS ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค.


3. Credentialed Request

XMLHttpRequest, fetch API, axios๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ณ„๋„์˜ ์˜ต์…˜ ์—†์ด ๋ธŒ๋ผ์šฐ์ €์˜ ์ฟ ํ‚ค ์ •๋ณด๋‚˜ ์ธ์ฆ ๊ด€๋ จ ํ—ค๋” (ex. Authorization ํ—ค๋”) ๋ฅผ ํ•จ๋ถ€๋กœ ์š”์ฒญ์— ๋‹ด์ง€ ์•Š๋Š”๋‹ค.

์ด๋•Œ withCredentials ์˜ต์…˜์„ true๋กœ ์„ค์ •ํ•˜๋ฉด cross origin์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ credential ์ •๋ณด๋ฅผ ๋‹ด์•„์„œ ๋ณด๋‚ธ๋‹ค. (fetch API์—์„œ๋Š” credentials ์˜ต์…˜์„ include๋กœ ์„ค์ •)

์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials : true๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด ์‘๋‹ต์„ ๊ฑฐ๋ถ€ํ•œ๋‹ค. ๋˜ํ•œ, Access-Control-Allow-Origin์— *๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋ช…์‹œ์ ์ธ URL์ด์–ด์•ผ ํ•œ๋‹ค.


๐Ÿšจ CORS ์ •์ฑ… ์œ„๋ฐ˜ํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•

์„œ๋ฒ„์—์„œ Access-Control-Allow-Origin ์•Œ๋งž๊ฒŒ ์„ค์ •ํ•˜๊ธฐ

  • *๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ชจ๋“  ์ถœ์ฒ˜์—์„œ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ ์ธก๋ฉด์—์„œ issue๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋˜๋„๋ก ๋ช…์‹œ์ ์ธ URL๋กœ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ Proxy ์„œ๋ฒ„ ์„ค์ •ํ•˜๊ธฐ

  • ํ”„๋ก์‹œ ์„œ๋ฒ„๋ฅผ ์„ค์ •ํ•˜๋ฉด CORS ์ •์ฑ…์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, http://localhost:3000์—์„œ http://localhost:8080๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‹ถ๋‹ค๊ณ  ํ•˜์ž. (๋‘˜์€ ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ cross origin์ด๋‹ค.)
  • ์ด๋•Œ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ http://localhost:8080์„ proxy ์„œ๋ฒ„๋กœ ์„ค์ •ํ•œ๋‹ค.
  • ๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ ์ธก์ด http://localhost:3000/api๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด http://localhost:8080/api๋กœ ์šฐํšŒํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

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



์ฐธ๊ณ 

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