ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CORS์™€ SOP, ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€?
    ์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ 2023. 3. 20. 01:20

    CORS์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ธฐ ์ „, ๋จผ์ € SOP๋ฅผ ์•Œ์•„๋ด์•ผ ํ•œ๋‹ค. CORS๋ž€ ๊ฒฐ๊ตญ SOP๊ฐ€ ์ง€์ผœ์ง€์ง€ ์•Š์•˜์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    SOP (Same-Origin-Policy)

    SOP๋ž€ ๋ง ๊ทธ๋Œ€๋กœ ๋™์ผํ•œ ์ถœ์ฒ˜์—์„œ๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ทœ์น™์„ ๊ฐ€์ง„ ์ •์ฑ…์ด๋‹ค. ๋‘ URL๊ฐ„์˜ Scheme, Host, Port์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๋ฉด SOP๋ฅผ ์œ„๋ฐ˜ํ•œ ๊ฒƒ์ด ๋œ๋‹ค.

    ์•„๋ž˜ ์˜ˆ์‹œ๋กœ ๊ฐ™์€ Origin์ธ์ง€ ์กฐ๊ธˆ ๋” ์•Œ์•„๋ณด์ž
    ๋‚˜์˜ ๋ธ”๋กœ๊ทธ ์ถœ์ฒ˜์ธ https://minju-k.tistory.com/์™€ ์ถœ์ฒ˜๋ฅผ ํ•œ๋ฒˆ ๋น„๊ตํ•ด๋ณด์ž.

     

     

    CORS (Cross-Origin Resource Sharing)

    CORS๋Š” ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ผ๊ณ  ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ต์ฐจ ์ถœ์ฒ˜๋ผ๋Š” ๊ฒƒ์€ ๊ฒฐ๊ตญ ๊ฐ™์€ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์•ž์„œ ์‚ดํŽด๋ณธ SOP์— ํ•ด๋‹น๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ฉด ๊ต์ฐจ ์ถœ์ฒ˜๋ผ๊ณ  ๋ณด๋Š” ๊ฒƒ์ด๊ณ , ์ด๋ ‡๊ฒŒ SOP ๊ฐ€ ์•„๋‹Œ ๊ณณ์—์„œ ์ž์›์„ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์„ ๋ง‰์•„์ฃผ๋Š”๊ฒŒ CORS์ •์ฑ…์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

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

     

    CORS๋Š” ๋ธŒ๋ผ์šฐ์ € ์ •์ฑ…์ด๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ ํ•  ๋•Œ์—๋Š” ์ด ์ •์ฑ…์ด ์ ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ, CORS ์ •์ฑ…์„ ์œ„๋ฐ˜ํ•˜๋Š” ๋ฆฌ์†Œ์Šค ์š”์ฒญ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ•ด๋„ ์„œ๋ฒ„ ์ชฝ ๋กœ๊ทธ์—๋Š” ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ตํ–ˆ๋‹ค๋Š” ๋กœ๊ทธ๋งŒ ๋‚จ๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ด์•ผ ํ•œ๋‹ค.

    CORS์˜ ๋™์ž‘๋ฐฉ์‹

    1. ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์— ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ๋•Œ์—๋Š” HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š”๋ฐ, ์ด ๋•Œ ๋ธŒ๋ผ์šฐ์ €๋Š” ์š”์ฒญ ํ—ค๋”์˜ Origin์ด๋ผ๋Š” ํ•„๋“ฑ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์ถœ์ฒ˜๋ฅผ ํ•จ๊ป˜ ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค.
    2. ์ดํ›„ ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ํ•  ๋•Œ, ์‘๋‹ต ํ—ค๋”์˜ Access-Control-Allow-Origin์ด๋ผ๋Š” ๊ฐ’์— ์ด ๋ฆฌ์†Œ์Šค๋ฅผ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋œ ์ถœ์ฒ˜๋ฅผ ๋‚ด๋ ค์ฃผ๋ฉด
    3. ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž์‹ ์ด ๋ณด๋ƒˆ๋˜ ์š”์ฒญ์˜ Origin๊ฐ’๊ณผ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ด์ค€ Access-Control-Allow-Origin์„ ๋น„๊ตํ•œ ํ›„ ์‘๋‹ต์ด ์œ ํšจํ•œ ์‘๋‹ต์ด๋ผ๋ฉด ์‚ฌ์šฉ, ์•„๋‹ˆ๋ผ๋ฉด CORS์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

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

    1. Preflight Request

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

     

    mdn์—์„œ ๊ฐ€์ ธ์˜จ ์˜ˆ์ œ๋กœ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž.
    ๋‚ด๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด POST๋กœ ์–ด๋–ค ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค๊ณ  ํ•ด๋ณด์ž. Content-type์ด application/xml์ด๊ณ , ์‚ฌ์šฉ์ž ์ •์˜ ํ—ค๋”๊ฐ€ ์„ค์ •๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์š”์ฒญ์€ ๋ธŒ๋ผ์šฐ์ €์— ์˜ํ•ด preflighted ์ฒ˜๋ฆฌ๊ฐ€ ๋œ๋‹ค.

    // preflight ์š”์ฒญ ์˜ˆ์ œ
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'https://bar.other/resources/post-here/');
    xhr.setRequestHeader('Ping-Other', 'pingpong');
    xhr.setRequestHeader('Content-Type', 'application/xml');
    xhr.onreadystatechange = handler;
    xhr.send('<person><name>Arun</name></person>');

     

    ์œ„ ์š”์ฒญ์„ ์‚ดํŽด๋ณด๋ฉด ๋ณธ ์š”์ฒญ์— ์•ž์„œ Preflight request๊ฐ€ ์ผ์–ด๋‚œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. OPTIONS ์š”์ฒญ์œผ๋กœ Origin์„ ์ „๋‹ฌํ–ˆ๊ณ , ์ด์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์„œ๋ฒ„๋Š” Access-Control-Allow-Origin์„ ํ†ตํ•ด ์ด ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ์ถœ์ฒ˜๊ฐ€ https:/foo.example์ด๋ผ๊ณ  ์•Œ๋ ค์ฃผ์—ˆ๋‹ค. ์š”์ฒญ์„ ๋ณด๋‚ธ Origin๊ณผ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต์œผ๋กœ ์ค€ ์ถœ์ฒ˜๊ฐ€ ๊ฐ™์œผ๋ฏ€๋กœ CORS ์ •์ฑ…์„ ์œ„๋ฐ˜ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •์ƒ์ ์œผ๋กœ ๋ณธ ์š”์ฒญ์ด ์ง„ํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.

     

    ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ์„œ๋ฒ„๊ฐ€ ๋‚ด๋ ค์ค€ Access-Control-Allow-Origin๊ฐ’์ด https://minju-k.com์ด๋ผ๊ณ  ํ–ˆ๋”๋ผ๋„ ์‘๋‹ต์„ ํ™•์ธํ•ด๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ 200 OK๊ฐ€ ๋‚ฌ์„ ๊ฒƒ์ด๊ณ , ํ•˜์ง€๋งŒ CORS์—๋Ÿฌ๊ฐ€ ๋‚ฌ์„ ๊ฒƒ์ด๋‹ค. ์‹ค์ œ๋กœ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์€ ์„œ๋ฒ„์—์„œ ์‘๋‹ต์„ ๋ฐ›์€ ํ›„ ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ค‘์š”ํ•œ ๊ฒƒ์€ ์˜ˆ๋น„ ์š”์ฒญ์˜ ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€๊ฐ€ ์•„๋‹ˆ๋ผ, ์‘๋‹ต ํ—ค๋”์— ์œ ํšจํ•œ Access-Control-Allow-Origin ๊ฐ’์ด ์กด์žฌํ•˜๋Š”๊ฐ€์ด๋‹ค.

    2. Simple Request

    ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ผ๋ถ€ ์š”์ฒญ์€ CORS preflight๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ณธ ์š”์ฒญ์„ ํ•˜๋Š” 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๋งŒ ํ—ˆ์šฉ๋œ๋‹ค.

    ์œ„์™€ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๋ฐ”๋กœ ์š”์ฒญ์„ ํ•˜๋ฉฐ Origin์„ ๋ณด๋‚ด๋ฉด, ์„œ๋ฒ„๋Š” ์ด์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ Access-Control-Allow-Origin ๊ฐ’์„ ๋‚ด๋ ค์ค€๋‹ค.

    3. Credentialed Request

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

     

    ๊ธฐ๋ณธ์ ์ธ XMLHttpRequest ๊ฐ์ฒด๋‚˜ fetch API๋Š” ๋ณ„๋„์˜ ์˜ต์…˜ ์—†์ด ๋ธŒ๋ผ์šฐ์ €์˜ ์ฟ ํ‚ค ์ •๋ณด๋‚˜ ์ธ์ฆ๊ณผ ๊ด€๋ จ๋œ ํ—ค๋”๋ฅผ ํ•จ๋ถ€๋กœ ์š”์ฒญ์— ๋‹ด์ง€ ์•Š๋Š”๋ฐ, ์ด ๋•Œ ์š”์ฒญ์— ์ธ์ฆ๊ณผ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์˜ต์…˜์ด ๋ฐ”๋กœ credentials ์˜ต์…˜์ด๋‹ค.

     

    ์ด ์˜ต์…˜์—๋Š” ์•„๋ž˜ 3 ๊ฐ€์ง€ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๋งŒ์•ฝ ๋‚ด๊ฐ€ same-origin์ด๋‚˜ include์™€ ๊ฐ™์€ ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์— ์ธ์ฆ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ๋‹ค๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•  ๋•Œ Access-Control-Allow-Origin ์™ธ์— ์ถ”๊ฐ€๋กœ ๋” ๊ฒ€์‚ฌ ์กฐ๊ฑด์„ ๊ฐ€์ ธ๊ฐ€ ํ™•์ธํ•˜๊ฒŒ ๋œ๋‹ค.

    ๊ทธ ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

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

    ๋”ฐ๋ผ์„œ ๋งŒ์•ฝ ๋‚ด๊ฐ€ ์•„๋ž˜ ์ฒ˜๋Ÿผ credentials ํ•„๋“œ์— include ๊ฐ’์„ ๋„ฃ์–ด ๋ณด๋ƒˆ๋‹ค๋ฉด, ์„œ๋ฒ„์— ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ๋˜์–ด ์žˆ์–ด๋„ CORS ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉฐ, Access-Control-Allow-Credentials๊ฐ’์ด ์—†๋‹ค๋ฉด CORS ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

    fetch('https://minju-k.com/feed.xml', {
      credentials: 'include', // Credentials ์˜ต์…˜ ๋ณ€๊ฒฝ!
    });

    CORS ์—๋Ÿฌ ํ•ด๊ฒฐํ•˜๊ธฐ

    CORS ์—๋Ÿฌ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•ด ๋ณด์•˜์œผ๋‹ˆ, ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผ ํ•˜๊ฒ ๋‹ค.

    ํ•ด๊ฒฐ๋ฐฉ๋ฒ• 1. Access-Control-Allow-Origin

    ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ ์„œ๋ฒ„์˜ Access-Control-Allow-Origin์— ๋‚ด๊ฐ€ ์š”์ฒญํ•˜๋Š” Origin์„ ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. Origin๊ณผ ํ•ด๋‹น ๊ฐ’์ด ๋‹ค๋ฅผ ๋•Œ์— CORS๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ด ๊ฐ’์„ ์„ธํŒ…ํ•˜๋ฉด CORS ์—๋Ÿฌ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด๋„ ๋‹น์—ฐํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

    * ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์ถœ์ฒ˜์—์„œ ์˜ค๋Š” ์š”์ฒญ์„ ๋‹ค ๋ฐ›๊ฒ ๋‹ค๊ณ  ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•  ๊ฒฝ์šฐ ์ด์ƒํ•œ ์ถœ์ฒ˜์—์„œ ์˜ค๋Š” ์š”์ฒญ๋„ ๋‹ค ๋ฐ›๊ฒŒ ๋˜๋ฏ€๋กœ ๋ณด์•ˆ์ ์ธ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๊ธฐ์— URL์„ ๋ช…์‹œํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์€ ๋ฐฉ์‹์ด๋‹ค.

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

    ํ”„๋ก ํŠธ์—”๋“œ ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด ์„œ๋ฒ„์—์„œ http://localhost:3000๊ณผ ๊ฐ™์€ ๋ฒ”์šฉ์  ์ถœ์ฒ˜๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋“œ๋ฌผ๊ธฐ ๋•Œ๋ฌธ์— CORS ์—๋Ÿฌ๋ฅผ ๋งˆ์ฃผ์น  ํ™•๋ฅ ์ด ๋†’๋‹ค. ์ด๋Ÿด ๋•Œ์—, ์„œ๋ฒ„์— ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ ํ—ค๋”์˜ Access-Control-Allow-Origin์— ๋„ฃ์–ด๋‹ฌ๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ ์™ธ์— ํ”„๋ก ํŠธ์—”๋“œ ๋‹จ์—์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ webpack-dev-server๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

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

    ์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด /api๋กœ ์‹œ์ž‘ํ•˜๋Š” URL๋กœ ๋ณด๋‚ด๋Š” ์š”์ฒญ์— ๋Œ€ํ•ด ๋ธŒ๋ผ์šฐ์ €๋Š” localhost:8000/api๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ์ง€๋งŒ, ์›นํŒฉ์ด https://api.minju-k.com์œผ๋กœ ์š”์ฒญ์„ ํ”„๋ก์‹ฑํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— CORS ์ •์ฑ…์„ ์ง€ํ‚จ ๊ฒƒ์ฒ˜๋Ÿผ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์†์ด๋ฉด์„œ๋„ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์„œ๋ฒ„์™€ ํ†ต์‹ ์„ ์ž์œ ๋กญ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    ๋‹ค๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ์‹ค์ œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ์›นํŒฉ์ด ์š”์ฒญ์„ ํ”„๋ก์‹œํ•ด์ฃผ์ง€๋งŒ ์‹ค์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์„œ๋ฒ„์— ์˜ฌ๋ฆฌ๋ฉด ๋”์ด์ƒ webpack-dev-server๊ฐ€ ๊ตฌ๋™ํ•˜๋Š” ํ™˜๊ฒฝ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

     

    ๋ฐฐํฌํ•  ๋•Œ, API๊ฐ€ ๋„๋ฉ”์ธ์—์„œ ์ œ๊ณต์ด ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์ง€๋งŒ, API์˜ ๋„๋ฉ”์ธ๊ณผ ์„œ๋น„์Šค์˜ ๋„๋ฉ”์ธ์ด ๋‹ค๋ฅด๋‹ค๋ฉด axios์˜ ๊ธ€๋กœ๋ฒŒ baseURL ์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

    axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? '/' : '{API ๋„๋ฉ”์ธ}';

    ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด ๊ฐœ๋ฐœํ™˜๊ฒฝ์—์„œ๋Š” ํ”„๋ก์‹œ ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜๊ณ , ์‹ค์ œ ํ”„๋กœ๋•์…˜์—์„œ๋Š” ์‹ค์ œ API ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ํ•˜๊ฒŒ ๋œ๋‹ค.

     

     

    https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

    https://evan-moon.github.io/2020/05/21/about-cors/#cors%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B8%B0%EB%B3%B8%EC%A0%81%EC%9D%B8-%EB%82%B4%EC%9A%A9

    https://velog.io/@jesop/SOP%EC%99%80-CORS

    ๋Œ“๊ธ€

Designed by Tistory.