CORS

S-rimยท2022๋…„ 8์›” 19์ผ
0
post-thumbnail

๐Ÿšจ Access to XMLHttpRequest at 'https://api.test.com/auth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

์ฝ˜์†”์—์„œ ์œ„๊ฐ™์€ ๋นจ๊ฐ„ ์—๋Ÿฌ๋ฉ”์„ธ์ง€๋ฅผ ๋ณธ ์ ์ด ๋‹ค๋“ค ํ•œ ๋ฒˆ์ฏค์€ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. CORS?? CORS๊ฐ€ ๋ญ๊ธธ๋ž˜, ๋ญ๊ฐ€ ์•ˆ๋œ๋‹ค๊ณ  ๋ป˜๊ฒ‹๊ฒŒ ์ž๊ธฐ์ฃผ์žฅ์„ ํ•ด๋Œ€๋Š” ๊ฑธ๊นŒ?

cors๋ž€?

Cross

Origin

Resource

Sharing

๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ผ๋Š” ๋œป์ด๋‹ค.

๊ทธ๋‹ˆ๊นŒ ๊ทธ๊ฒŒ ๋ญ”๋””?

๋™์ผํ•œ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ •์ฑ…์ด๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ฝ˜์†”์ฐฝ์—์„œ ๋งŒ๋‚œ CORS์—๋Ÿฌ๋Š” CORS ์ •์ฑ…์„ ์œ„๋ฐ˜ํ–ˆ๋‹ค๊ณ  ์•Œ๋ ค์ค€ ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿผ ์ถœ์ฒ˜๋Š” ๋ญ˜ ๋œปํ•˜๋Š” ๊ฑธ๊นŒ?

์—ฌ๊ธฐ์„œ ์ถœ์ฒ˜๋Š” ์•„์ฃผ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด URL์ฃผ์†Œ ์ด๋‹ค.
๊ทธ๋Ÿผ URL์ด ํ† ์”จํ•˜๋‚˜ ์•ˆํ‹€๋ฆฌ๊ณ  ๋˜‘๊ฐ™์•„์•ผ ๋™์ผ ์ถœ์ฒ˜๊ณ , ํ•œ ๊ธ€์ž๋ผ๋„ ํ‹€๋ฆฌ๋ฉด ๋‹ค๋ฅธ ์ถœ์ฒ˜์ผ๊นŒ?

์•„๋‹ˆ๋‹ค. URL์—์„œ ํ”„๋กœํ† ์ฝœ, ํ˜ธ์ŠคํŠธ, ํฌํŠธ๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์œผ๋ฉด ๋™์ผ ์ถœ์ฒ˜๋ผ๊ณ  ํ•œ๋‹ค.

https://www.test.com/users?page=1

์œ„ URL์„ ๊ตฌ์„ฑ์š”์†Œ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ๋œ๋‹ค.

https:// - Protocol

www.bubbletap.com - Host

/users - Path

?page=1 - Query String

์ถœ์ฒ˜ ๋‚ด์˜ ํฌํŠธ ๋ฒˆํ˜ธ๋Š” ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ฐ ์›น์—์„œ ์‚ฌ์šฉํ•˜๋Š” HTTP, HTTPS ํ”„๋กœํ† ์ฝœ์˜ ๊ธฐ๋ณธ ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ์ •ํ•ด์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ https://naver.com:123 ์ฒ˜๋Ÿผ ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ํฌํŠธ ๋ฒˆํ˜ธ๊นŒ์ง€ ์ผ์น˜ํ•ด์•ผ ๋™์ผ ์ถœ์ฒ˜๋กœ ์ธ์ •๋œ๋‹ค.

์ž๊พธ ๋™์ผ์ถœ์ฒ˜ ๋™์ผ์ถœ์ฒ˜ ๊ฑฐ๋ฆฌ๋Š”๋ฐ ๊ทธ๋Ÿผ ๋™์ผ ์ถœ์ฒ˜ ๊ด€๋ จ ์ •์ฑ…๋„ ์žˆ์„๊นŒ?

SOP๋ผ๊ณ  ์žˆ๋‹ค.

SOP๋ž€?

Same

Origin

Policy

๊ฐ™์€ ์ถœ์ฒ˜์—์„œ๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค ๋ผ๋Š” ๊ทœ์น™์„ ๊ฐ€์ง„ ์ •์ฑ…์ด๋‹ค.


์Œ? ๊ทธ๋Ÿผ ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ •์ฑ…์ธ CORS๋ž‘ ๋ถ€๋”ชํžˆ์ง€์•Š๋‚˜? ์Ÿค๋Š” ํ—ˆ์šฉํ•œ๋‹ค๋Š”๋ฐ... ์–˜๋Š” ๊ฐ™์€๋ฐ์„œ๋งŒ ๊ณต์œ ํ•˜๋ผ๊ทธ๋Ÿฌ๊ณ ... ๋Œ€์ฒด ๋ˆ„๊ตฌ ๋ง์„ ๋“ค์œผ๋ผ๋Š”๊ฑด์ง€...

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

๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ CORS ์ •์ฑ…์„ ์ง€ํ‚จ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์ด๋‹ค.

๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ •์ฑ…์ธ CORS๊ฐ€ SOP ์ •์ฑ…์˜ ์˜ˆ์™ธ ์ •์ฑ…์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ ์ถœ์ฒ˜๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๋ฉด SOP ์ •์ฑ…์„ ์œ„๋ฐ˜ํ•œ ๊ฒƒ์ด๊ณ ,
SOP ์˜ˆ์™ธ ์กฐํ•ญ์ธ CORS ์ •์ฑ…๋งˆ์ € ์ง€ํ‚ค์ง€ ์•Š์œผ๋ฉด ์•„์˜ˆ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฐ ์ •์ฑ…๋“ค์„ ๊นŒ๋‹ค๋กญ๊ณ  ๊ท€์ฐฎ๊ธฐ๋งŒํ•œ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„œ๋กœ ํ†ต์‹ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์•„๋ฌด๋Ÿฐ ์ œ์•ฝ๋„ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด
์•…์˜๋ฅผ ๊ฐ€์ง„ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ CSRF(Cross-Site Request Forgery)๋‚˜ XSS(Cross-Site Scripting)์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ํƒˆ์ทจํ•˜๊ธฐ๊ฐ€ ๋„ˆ๋ฌด๋‚˜๋„ ์‰ฌ์›Œ์ง„๋‹ค.

CORS๋ผ๋Š” ๋ฐฉ์–ด๋ง‰์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์•ˆ์ „ํ•˜๋‹ค๋Š” ์ตœ์†Œํ•œ์˜ ๋ณด์žฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

CORS๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ๋•Œ๋Š” HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋•Œ ๋ธŒ๋ผ์šฐ์ €๋Š” ์š”์ฒญ ํ—ค๋”์— Origin์ด๋ผ๋Š” ํ•„๋“œ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ถœ์ฒ˜๋ฅผ ํ•จ๊ป˜ ๋‹ด์•„๋ณด๋‚ธ๋‹ค.

์ดํ›„ ์„œ๋ฒ„๊ฐ€ ์ด ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ํ—ค๋”์˜ Access-Control-Allow-Origin์ด๋ผ๋Š” ๊ฐ’์— ํ—ˆ์šฉ๋œ ์ถœ์ฒ˜๊ฐ’์„ ๋‚ด๋ ค์ฃผ๊ณ , ๋ธŒ๋ผ์šฐ์ €๋Š” Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ๋‚ด๋ ค์ค€ Access-Control-Allow-Origin์„ ๋น„๊ตํ•ด ์œ ํšจํ•œ ์‘๋‹ต์ธ์ง€ ์•„๋‹Œ์ง€ ๊ฒฐ์ •ํ•œ๋‹ค.

์ด๊ฑด ๊ธฐ๋ณธ์ ์ธ ํ๋ฆ„์ด๊ณ , CORS๊ฐ€ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์€ 3๊ฐ€์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋œ๋‹ค.

  1. Preflight Request

์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์žฅ ์ž์ฃผ ๋งˆ์ถ”์ง€๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ, ์ด๋ฆ„์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์˜ˆ๋น„ ์š”์ฒญ๊ณผ ๋ณธ ์š”์ฒญ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋ธŒ๋ผ์šฐ์ € ์Šค์Šค๋กœ ์ด ์š”์ฒญ์ด ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์—ฌ๊ธฐ์„œ ์˜ˆ๋น„ ์š”์ฒญ์„ Preflight๋ผ๊ณ  ๋ถ€๋ฅด๊ณ , ์˜ˆ๋น„ ์š”์ฒญ์—๋Š” HTTP ๋ฉ”์†Œ๋“œ ์ค‘ OPTION ๋ฉ”์†Œ๋“œ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

1. fetch ๋ช…๋ น

2. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋ƒ„

3. ์„œ๋ฒ„๊ฐ€ ํ—ˆ์šฉ ๋˜๋Š” ๊ธˆ์ง€ ์ •๋ณด๋ฅผ ์‘๋‹ต ํ—ค๋”์— ๋‹ด์•„ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์‘๋‹ต

4. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž์‹ ์ด ๋ณด๋‚ธ ์˜ˆ๋น„ ์š”์ฒญ๊ณผ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•ด์ค€ ํ—ˆ์šฉ ์ •์ฑ…์„ ๋น„๊ตํ•ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด ๋ณธ ์š”์ฒญ์„ ๋ณด๋ƒ„

5. ์„œ๋ฒ„๊ฐ€ ๋ณธ ์š”์ฒญ์— ๋Œ€ํ•ด ์‘๋‹ต

6. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ตœ์ข…์ ์œผ๋กœ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๊ฒŒ ๋„˜๊ฒจ์คŒ

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

  1. Simple Request

์ •์‹ ๋ช…์นญ์€ ์•„๋‹ˆ์ง€๋งŒ MDN ๋ฌธ์„œ์—์„œ Simple Request๋ผ๊ณ  ๋ถ€๋ฅด๊ณ  ์žˆ๋‹ค.

์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์„œ๋ฒ„์—๊ฒŒ ๋ณธ ์š”์ฒญ๋งŒ ๋ณด๋‚ธ ๋’ค, ์„œ๋ฒ„๊ฐ€ ์ด์— ๋Œ€ํ•œ ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Origin๊ณผ ๊ฐ™์€ ๊ฐ’์„ ๋ณด๋‚ด์ฃผ๋ฉด, ๊ทธ ๋•Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ CORS ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

1๋ฒˆ ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ๋ฐฉ์‹๊ณผ ์˜ˆ๋น„ ์š”์ฒญ ์œ ๋ฌด๋งŒ ๋‹ค๋ฅด๋‹ค.

์˜ค? ๊ทธ๋Ÿผ ์˜ˆ๋น„์š”์ฒญ ๋ณด๋‚ด๊ธฐ ๊ท€์ฐฎ์„ํ…๋ฐ ํ•ญ์ƒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€?

์•„๋ฌด๋•Œ๋‚˜ ๊ฐ€๋Šฅํ•œ ๊ฑด ์•„๋‹ˆ๊ณ  ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•  ์‹œ์—๋งŒ ์˜ˆ๋น„ ์š”์ฒญ ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
๊ทธ ์กฐ๊ฑด์€ 3๊ฐ€์ง€์ธ๋ฐ, ๋ชจ๋‘ ๋งŒ์กฑ ์‹œํ‚ค๊ธฐ์—๋Š” ์‰ฝ์ง€ ์•Š๋‹ค.

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๋งŒ ํ—ˆ์šฉ๋œ๋‹ค.

๊ฐ€๋Šฅํ•œ๊ฐ€?

1. PUT์ด๋‚˜ DELETE ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค.

2. ๋ช…์‹œ๋œ ํ—ค๋”๋“ค์€ ์ •๋ง ๊ธฐ๋ณธ์ ์ธ ํ—ค๋”๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•œ ์ƒ์šฉ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ด ํ—ค๋”๋“ค ์™ธ์— 
์ถ”๊ฐ€์ ์ธ ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋Š” ๋งค์šฐ ์ ๋‹ค. Authorization ํ—ค๋” ์กฐ์ฐจ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

3. ๋Œ€๋ถ€๋ถ„์˜ HTTP API๋Š” text/xml์ด๋‚˜ application/json ์ปจํ…์ธ  ํƒ€์ž…์„
๊ฐ€์ง€๋„๋ก ์„ค๊ณ„๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค์ƒ ์ด ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ค๋Š” ์ƒํ™ฉ์„ ๋งŒ๋“ค๊ธฐ๋Š” ์‰ฝ์ง€ ์•Š๋‹ค.

์œ„์ฒ˜๋Ÿผ ์กฐ๊ฑด์ด ๋งŽ์ด ๊นŒ๋‹ค๋กญ๊ธฐ ๋•Œ๋ฌธ์— ์ž˜ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.

  1. Credentialed Request

์š”์ฒญ ํ—ค๋”์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ, CORS์˜ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์‹๋ณด๋‹ค ๋‹ค๋ฅธ ์ถœ์ฒ˜ ๊ฐ„ ํ†ต์‹ ์—์„œ ์ข€ ๋” ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” ํ”„๋ก ํŠธ, ์„œ๋ฒ„ ์–‘์ธก ๋ชจ๋‘ CORS ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.

ํ”„๋ก ํŠธ ์ธก์—์„œ๋Š” ์š”์ฒญ ํ—ค๋”์— withCredentials : true ๋ฅผ, ์„œ๋ฒ„ ์ธก์—์„œ๋Š” ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials : true ๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค.

์š”์ฒญ์— ์ธ์ฆ๊ณผ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” credentials ์˜ต์…˜ ๊ฐ’์œผ๋กœ ๊ฒ€์‚ฌ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

same-origin (๊ธฐ๋ณธ๊ฐ’) - ๊ฐ™์€ ์ถœ์ฒ˜ ๊ฐ„ ์š”์ฒญ์—๋งŒ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค

include - ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค

omit - ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์ง€ ์•Š๋Š”๋‹ค

Access-Control-Allow-Origin ๊ฐ’์œผ๋กœ ๋ชจ๋“  ์ถœ์ฒ˜๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ์ธ *๋ฅผ ์„ค์ •ํ–ˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ๋•Œ CORS ์ •์ฑ… ์œ„๋ฐ˜์œผ๋กœ ์ธํ•œ ์ œ์•ฝ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.
๊ทธ๋ž˜์„œ http://localhost:8000๊ณผ ๊ฐ™์€ ๋กœ์ปฌ์˜ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋„ fetch API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์Œ๋Œ€๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ credentials ์˜ต์…˜์„ ๋ชจ๋“  ์š”์ฒญ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„ include๋กœ ์ ์šฉํ•œ๋‹ค๋ฉด, ์„œ๋ฒ„ ์ธก์—์„œ Access-Control-Allow-Origin ์„ ์„ค์ •ํ•  ๋•Œ, *๋กœ ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” ๋งŒํผ ์ถœ์ฒ˜๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ธŒ๋ผ์šฐ์ € ์ธ์ฆ ๋ชจ๋“œ๊ฐ€ include์ผ ๊ฒฝ์šฐ, Access-Control-Allow-Origin์—๋Š” *๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , ๋ช…์‹œ์ ์ธ URL์ด์–ด์•ผํ•œ๋‹ค.

CORS๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•

Access-Control-Allow-Origin ์„ค์ •ํ•˜๊ธฐ

*๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŽธํ•˜๊ธฐ์•ผ ํ•˜๊ฒ ์ง€๋งŒ ์–ด๋””์„œ ์˜ค๋Š” ์ง€๋„ ๋ชจ๋ฅด๋Š” ์š”์ฒญ๊นŒ์ง€ ๋‹ค ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ท€์ฐฎ๋”๋ผ๋„ ์ถœ์ฒ˜๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Webpack Dev Server๋กœ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹ฑ ํ•˜๊ธฐ.

ํ”„๋ก ํŠธ์ชฝ ๋กœ์ปฌ์—์„œ CORS ์ •์ฑ…์„ ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

module.exports = {
devServer: {
    proxy: {
    '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        pathRewrite: { '^/api': '' },
    },
    }
}
}

์ด ์ฝ”๋“œ๋ฅผ ํ’€์ดํ•˜๋ฉด, ๋’ค์—์„œ ์›นํŒฉ์ด https://api.example.com์œผ๋กœ ์š”์ฒญ์„ ํ”„๋ก์‹ฑํ•ด์„œ ๋งˆ์น˜ CORS ์ •์ฑ…์„ ์ง€ํ‚จ ๊ฒƒ์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์†์ด๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ํ”„๋ก์‹ฑ์„ ํ†ตํ•ด CORS ์ •์ฑ…์„ ์šฐํšŒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋ฌผ๋ก  ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฆฌ์•กํŠธ๋กœ ๋งŒ๋“  ์„œ๋น„์Šค์™€ api๊ฐ€ ๋™์ผํ•œ ๋„๋ฉ”์ธ์—์„œ ์ œ๊ณต ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด๋Œ€๋กœ ๊ณ„์† ์ง„ํ–‰ํ•˜๋ฉด ๋˜์ง€๋งŒ, ๋งŒ์•ฝ์— api์˜ ๋„๋ฉ”์ธ๊ณผ ์„œ๋น„์Šค์˜ ๋„๋ฉ”์ธ์ด ๋‹ค๋ฅด๋‹ค๋ฉด ๊ธ€๋กœ๋ฒŒ baseURL์„ ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

API ์„œ๋ฒ„์˜ ์ถœ์ฒ˜๋Š” https://api.example.com์ด๊ณ  ํด๋ผ์ด์–ธํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„œ๋น™ํ•˜๋Š” ์„œ๋ฒ„์˜ ์ถœ์ฒ˜๋Š” https://www.example.com์ด๋ผ๋ฉด

fetch('/api/test');๋ฅผ ํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๋กœ์ปฌํ™˜๊ฒฝ์—์„œ๋Š”
GET https://api.example.com/test 200 OK

์‹ค์ œ ์„œ๋ฒ„
GET https://www.example.com/api/test 404 Not Found

์ด ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด process.env.NODE_ENV์™€ ๊ฐ™์€ ๋นŒ๋“œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„๊ธฐ ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœ ํ•  ๋•Œ proxy ๋ฅผ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฑ์—”๋“œ ์ชฝ์—์„œ ๊ฐœ๋ฐœ์„œ๋ฒ„๋ฅผ ์œ„ํ•œ CORS ์„ค์ •์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๊ฝค๋‚˜ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์šด์˜ ํ™˜๊ฒฝ๋ณด๋‹ค ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์“ฐ๊ธฐ์— ์šฉ์ดํ•˜๊ณ , ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ ์šด์˜ ํ™˜๊ฒฝ์—์„œ CORS ์ •์ฑ… ์œ„๋ฐ˜ ๋ฌธ์ œ๋ฅผ ํ”„๋ก ํŠธ์—์„œ๋งŒ ํ•ด๊ฒฐํ•˜๊ธฐ์—” ์–ด๋ ค์›€์ด ์žˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— CORS๋Š” ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ ์–ด๋Š ํ•œ ์ชฝ๋งŒ ์‹ ๊ฒฝ์จ์•ผ๋  ๊ฒŒ ์•„๋‹ˆ๋ผ, ๋ชจ๋‘ CORS์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

profile
๐Ÿค—

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