์์ฃผ ๋ง์ฃผ์น๋ CORS
์ค๋ฅ
ํ๋ก ํธ์๋ ํ๋ก์ ํธ๋ฅผ ํ ๋ ์์ฃผ ๋ง์ฃผ์น๋ ์ค๋ฅ ์ค ํ๋๋ก CORS
๊ฐ ์๋ค. ํ ์ด ํ๋ก์ ํธ๋ฅผ ํ ๋ API๋ฅผ ๊ฐ์ ธ๊ฐ ์ธ ๋๋ ๋น๋ฒํ๊ฒ ๋ฐ์ํ๊ณ , ํ์
์์ ๋ฐฑ์๋/ํ๋ก ํธ์๋ ์๋ฒ๋ฅผ ๋ค๋ฅด๊ฒ ๊ตฌ์ถํ๊ณ ๊ฐ๋ฐํ ๋๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค. ํ ์ด ํ๋ก์ ํธ๋ฅผ ํ ๋๋ ํ ์ค ์ฝ๋๋ฅผ ๋ฃ์ด ํ๋ก์๋ฅผ ์ฐํํ๋๋ก ํ๋ฉฐ API๋ฅผ ์ฐ๊ฑฐ๋(a), webpack ์ค์ ํ์ผ์ ๊ฐ๋ฐ ์์ ์ฌ์ฉํ ์ ์๊ฒ proxy ์ค์ (b)์ ํด์ฃผ๊ณค ํ๋ค. ์ข ๋ ํฐ ๊ท๋ชจ์ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์์๊ฒ CORS ํด๊ฒฐ์ ์ํด ํ์กฐ๋ฅผ ์์ฒญํด์ ํด๊ฒฐํ๋ค. (์ฌ์ ์ง์์ด ๋ถ์กฑํ์ ๋ ํ๋ก ํธ์๋ ๋จ์์ ์ค์์ธ๊ฐ ์ถ์ด์ ์จ๊ฐ ์๋ฃ๋ฅผ ์ฐพ์๋ณด๋ฉด์ ๋ฐฉ๋ฒ์ ๊ฐ๊ตฌํด๋ดค์ง๋ง AWS ์๋ฒ ์ค์ ํ์ด์ง์์ ๋จ ํ ๋ฒ์ ํด๋ฆญ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ์๋ค...)
// Case a:
const proxy = 'https://secret-ocean-49799.herokuapp.com/'
const some_api = `${proxy}https://api.example.com`;
fetch(some_api)
.then(res => {
return res.json();
})
.catch(err => {
console.log(err)
})
// Case b:
// webpack.config.js
// ..
devServer: {
port: 4000,
open: true,
proxy: {
'/': 'http://localhost'
}
},
// ..
CORS
๊ฐ ํ์ํ ์ด์
์ฒ์์๋ CORS ์ค๋ฅ๊ฐ ๊ต์ฅํ ๊ท์ฐฎ๊ณ ๊น๋ค๋ก์ ๋๋ฐ, CORS๊ฐ ์ ์์๋์๋์ง๋ฅผ ์๊ฐํ๋ฉด, ๋ง๋ฅ ๊ท์ฐฎ์ํ ๋งํ ๋ฌธ์ ๋ ์๋์๋ค. CORS๋ Cross-Origin-Resource-Sharing์ ์ค์๋ง๋ก SOP(Same-origin-policy)๋ฅผ ์์ธ์ ์ผ๋ก ํ์ฉํ๊ธฐ ์ํด ์๊ฒจ๋ ์ ์ฑ ์ด๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ธ๋ผ์ฐ์ ์ ๋์ ๋๋ฉด์ ๋์ ์ด๊ณ , ํ์ ์ ์ธ ์ผ์ด ๊ฐ๋ฅํด์ก์ง๋ง, ๊ทธ๋งํผ ๋ณด์์ ์ํ๋๊ฐ ์ฌ๋ผ๊ฐ ํฐ๋ผ ๊ทธ ์ฆ์๋ถํฐ ๊ฐ์ ์ถ์ฒ์ ๋ฆฌ์์คํ๊ณ ๋ง ์ํธ์์ฉํ๋ค๋ ๋ฃฐ์ด ์ถ๊ฐ๋์๋ค.
ํ์ง๋ง, ์์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ ์๋ฒ๋ฅผ ๋ค๋ฅด๊ฒ ๊ตฌ์ถํ๊ณ ๊ฐ๋ฐํ๊ธฐ๋ ํ๋ ๋ฑ ๊ฐ์ ์ถ์ฒ(Resource)๊ฐ ์๋ ๊ฒฝ์ฐ์ ์ํตํด์ผ ํ ์ผ์ด ์๊ฒผ๋ค. ์ด๋ฅผ ์ํ ์ ์ฑ
์ด CORS์ด๋ค. ์ด๋ '์ถ์ฒ'๋ ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ๊ฐ ๊ฐ์ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์ ์ถ์ฒ๋ผ ๋งํ๋ค. cross-origin
์ ๋ค๋ฅธ ์ถ์ฒ๋ก ์ดํดํ๋ฉด ์ข๋ค.
CORS Requests
์น ๋ธ๋ผ์ฐ์ ์์์ ์น ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ค๋ฅธ ์ถ์ฒ์ ์์์ ์์ฒญํ ๋ ์ฐ๋ฆฌ๋ ์ด๋ฅผ cross origin requests๋ผ ๋ถ๋ฅด๋ฉฐ, CORS Preflighted Requests
๊ทธ๋ฆฌ๊ณ simple requests
์ด๋ ๊ฒ ํฌ๊ฒ ๋ ๊ฐ์ง ์ข
๋ฅ๋ก ๋๋ ๋ณผ ์ ์๋ค.
CORS Preflighted Requests
pre
๋ผ๋ ์ ๋์ด๊ฐ ์๋ฏธํ๋ ๊ฒ์ฒ๋ผ, ๋ฏธ๋ฆฌ ์์ฒญ์ ๋ณด๋ด ์์ผ๋ก ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ HTTP ์์ฒญ์ ์์ ์ธ๋ฐ ์ด๊ฒ์ด ๊ฐ๋ฅํ์ง ๊ฒํ ํ๋ ์์ฒญ์ด๋ค. OPTION ๋ฉ์๋๋ฅผ ํตํด ๋ณด๋ธ๋ค.
Simple Requests
๋ฐ๋ฉด ๋จ์ ์์ฒญ์ preflighted request๋ฅผ ์๋ตํ๋ค. ๋์ ํน์ HTTP Method, ํน์ HTTP Header๋ฅผ ๊ฐ์ถ๊ณ ์์ ๋๋ง ๊ฐ๋ฅํ ์์ฒญ์ด๋ค.
https://foo.example
์ ์น ํ์ด์ง์์ https://bar.other
์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๊ณ ์ ํ ๋๋ฅผ ์ดํด๋ณด์. ์๋ ๊ฐ์ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด๋ณผ ์ ์๋ค.
const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';
xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();
ํด๋ผ์ด์ธํธ์์ ํ์ํ ์์์ ๊ฐ์ง ์๋ฒ์ ์ฃผ์(https://bar.other/resources/public-data/
)๋ฅผ ์์ฒญํ ๋(c), ์๋ฒ๋ ์๋์ฒ๋ผ CORS ํค๋๋ฅผ ํตํด ์๋ตํ ๊ฒ์ด๋ค.(d)
// Case C :
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
// Case D:
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[โฆXML Dataโฆ]
์ด๋ ๊ฒ ์๋ฒ๊ฐ ์๋ตํ๋ฉด์ Access-Control-Allow-Origin
ํค๋๋ฅผ ๋ณด๋ด์ฃผ๊ณ ์๋๋ฐ, ๊ฐ์ด *
์์ผ๋ ์นด๋๋ก ๋์ด ์๋ค. ๋ฆฌ์์ค๋ ์ด๋ค origin์์๋ ์ ๊ทผ ๊ฐ๋ฅํ๋ค๋ ํ์์ด๋ค. ํธํ์ง๋ง, ๋ชจ๋ ๋๋ฉ์ธ์์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค๋ ๋ป์ด๋ฏ๋ก, ๋ณด์ ์ ์ทจ์ฝํ๋ค.
๋ณด์์ ์กฐ๊ธ ๋ ๊ฐํํ๋ฉด ์๋์ฒ๋ผ ์์ฑํ ์๋ ์๋ค.
Access-Control-Allow-Origin: https://foo.example
์ด์ ์ ๋ฆฌ์์ค๋ก๋ถํฐ ์ค๋ ์์ฒญ๋ง ํ์ฉํ๋ค๋ ์๋ฏธ์ด๋ค.
Reference
'๐ฉโ๐ป > Web' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SVG] JavaScript, CSS๋ฅผ ํ์ฉํ Path ๊ธฐ๋ฐ ํ ์คํธ ์ ๋๋ฉ์ด์ (0) | 2021.01.30 |
---|