์ฃผ๋์ด ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์๊ฒ CORS๋ ์ด๋ ค์ด ๋ฌธ์ ์ค์ ํ๋๋ผ๊ณ ์๊ฐํ๋ค.
๋ณด์ ๊ด๋ จ๋ ์ด๋ค ์ด์ ๋๋ฌธ์ ์๋ฌ๋ฅผ ๋ธ๋ค๋๊ฒ๊น์ง ์๊ฒ ๋๋ฐ, ์๋ฌ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด ๋ง๋งํ๋ค.
ํ์คํ ๊ฐ๋ฐ์๋ก ๊ฐ๋ฐ์ ์ปค๋ฆฌ์ด๋ฅผ ์ด์ด๋๊ฐ๋ฉด์, ์์ธ๋ก ๋ง์ ๊ฐ๋ฐ์๋ค์ด (์ฃผ๋์ด ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ , ์๋๋ ์๊ด์์ด) CORS์ ๋ํด ์คํดํ๊ณ ์๋ ๋ชจ์ต์ ๋ณด์๋ค. ๋ CORS์๋ฌ๋ฅผ ํด๊ฒฐํ๋ ๋ง์ ๋ฐฉ๋ฒ์ด ์ด๋ฏธ ์กด์ฌํ์ง๋ง, ๊ทธ๊ฒ๋ค์ ์ ๋ชจ๋ฅด๋ ์ฌ๋๋ค์ด ๋ง์๋ค๋๊ฑธ ์๊ฒ๋์๋ค.
CORS์ ๋ํด ์ฌ๋๋ค์ด ์ฝ๊ฒ ํ ๋งํ ์คํด ๋ช๊ฐ์ง๋ฅผ ๋ฐ๋ก์ก๊ณ , CORS๋ก ์ธํ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ ๋ช๊ฐ์ง ์ ์ํด๋ณด๊ฒ ๋ค.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ๋ง ํด๋ณธ ์น๊ฐ๋ฐ์๋ผ๋ฉด ํด๋ณผ๋งํ CORS์ ๋ํ ์คํด๊ฐ ๋ช๊ฐ์ง ์๋ค. ์ด๊ฒ๋ค์ ํ๊ณ ๋์ ํด๊ฒฐ๋ฒ์ ์จ๋ณด๊ฒ ๋ค.
CORS๋ CSRF ๋ผ๊ณ ๋ถ๋ฆฌ๋ ๋ธ๋ผ์ฐ์ ์ทจ์ฝ์ ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ธ๋ผ์ฐ์ ์ฌ์ฉ์๋ฅผ ๋ณดํธํ๊ธฐ ์ํด ๋ง๋ ๊ธฐ๋ฅ์ด๋ค.
HTTP ํ์ค ์คํ์ ํฌํจ๋์ด ์๊ณ , CORS ๊ด๋ จ ๊ธฐ๋ฅ์ ๊ตฌํ์ ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ฌ์๊ฒ ์ฑ ์์ด ์๋ค. ์น ํ์ค ๊ธฐ์ ์ ๋ฐ๋ฅด๋ ์ ์์ ์ด๊ณ ์ผ๋ฐ์ ์ธ ๋ธ๋ผ์ฐ์ ๋ผ๋ฉด CORS ์ญ์ ํ์ค ์คํ์ ๋งก๊ฒ ๊ตฌํ๋์ด ์๋ค.
์ฌ๊ธฐ์ ์ผ๋ฐ์ ์ธ ๋ธ๋ผ์ฐ์ ๋ผ ํจ์, ์ต์คํ๋ก๋ฌ๋ฅผ ์ ์ธํ ํฌ๋กฌ, ์ฌํ๋ฆฌ, ํ์ด์ดํญ์ค, ์คํ๋ผ ๋ฑ์ ๋งํ๋ค. ์ฆ, ํ๋ฒํ ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ์์ฝ๊ฒ ๋ค์ด๋ก๋ ๋ฐ์์ ์ธ์ ์๋ ์ข ๋ฅ์ (IE ์ ์ธ...) ๋ธ๋ผ์ฐ์ ๋ค์ด๋ค.
ํฌ๋ก๋ฏธ์ ๊ธฐ๋ฐ์ ๋ธ๋ผ์ฐ์ ์ค์์, ์ค์ํ ๋ณด์์ ์ฑ ๋ค์ ์๋์ ์ผ๋ก ๋นํ์ฑํ์ํจ ๋ฒ์ ์ ํน์ดํ ๋ธ๋ผ์ฐ์ ๋ค๋ ์กด์ฌํ๋๋ฐ, ์ด ๊ฒฝ์ฐ CORS ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ ์๋ ์๋ค. (๋จ, ์ด๊ฑด CORS ์๋ฌ์ ๋ํ ์ฌ๋ฐ๋ฅธ ํด๊ฒฐ๋ฒ์ ์๋๋ค.)
CORS ์ ์ฑ
์ ์๋ฒ์ ์ ์ฅ๋์ด์์ผ๋ฉฐ, ์ ์ฅ๋ CORS ์ ์ฑ
์ ๋ธ๋ผ์ฐ์ ์๊ฒ ๋ณด๋ด์ฃผ๋ ์ผ์ ์๋ฒ๊ฐ ๋งก๊ณ ์๊ธด ํ๋ค.
ํ์ง๋ง, ๊ทธ CORS์ ์ฑ
์ ๋ณด๋ด๋ฌ๋ผ๊ณ ์๋ฒ์๊ฒ ์์ฒญํ๋๊ฑด ๋ธ๋ผ์ฐ์ ์ด๋ค.
์ฆ, CORS ์๋ฌ๋ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ํ๋ค.
CORS๋ ๋ณด์์ ์ฑ ์ค ํ๋์ด์ง๋ง, ๋ณดํธ์ ๋์์ ์๋ฒ๊ฐ ์๋๋ค.
CORS๋ HTTP ์์ฒญ ํค๋ ์ค์์ Origin
์ด๋ผ๋ ํค๋์ ๊ด๋ จ๋์ด ์๋ค.
๋ธ๋ผ์ฐ์ ์์ ajax ์์ฒญ์ด ๋ฐ์ํ์๋, ํ์ฌ ํ์ด์ง์ ์ฃผ์์ฐฝ์ ์ ํ ๋๋ฉ์ธ๊ณผ, ajax ์์ฒญ ๋์ url์ ๋๋ฉ์ธ์ด ๊ฐ์ ๊ฒฝ์ฐ๋ ์์ง๋ง, ๋ค๋ฅธ ๊ฒฝ์ฐ๋ ์๋ค. ์ ์์ ์ํฉ์ Same Origin Request (๋์ผ์ถ์ฒ ์์ฒญ) ์ด๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ, ํ์๋ฅผ Cross Origin Request (๊ต์ฐจ์ถ์ฒ ์์ฒญ) ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๋ธ๋ผ์ฐ์ ์์ cross origin ์์ฒญ์ด ๋ฐ์ํ์๋, ๋ธ๋ผ์ฐ์ ๋ ํด๋น ์์ฒญ์ origin
ํค๋๋ฅผ ์๋์ผ๋ก ๋ถ์ธ๋ค. ํ์ฌ ํ์ด์ง์ ๋๋ฉ์ธ์ด Origin ํค๋์ ๊ฐ์ด ๋๋ค.
http://www.abc.com/page/1
ํ์ด์ง์์http://www.abc.com/api/products
๋ก ajax ์์ฒญ์ด ๋ฐ์ํ ๊ฒฝ์ฐ, ์์ฒญ์ ํ์ฌํ์ด์ง์ ์์ฒญ ๋์์ ๋๋ฉ์ธ์ด ๊ฐ์ผ๋ฏ๋ก same origin request (๋์ผ์ถ์ฒ์์ฒญ) ์ด๋ผ๊ณ ํ ์ ์๋ค.
http://www.abc.com/page/1
ํ์ด์ง์์http://www.def.com/api/user
์ผ๋ก ajax ์์ฒญ์ ๋ณด๋ผ๊ฒฝ์ฐ, ์์ฒญ์ ํ์ฌํ์ด์ง์ ์์ฒญ ๋์์ ๋๋ฉ์ธ์ด ๋ค๋ฅด๋ฏ๋ก cross origin request (๊ต์ฐจ์ถ์ฒ์์ฒญ) ์ด๋ผ๊ณ ํ ์ ์๋ค.
๋ธ๋ผ์ฐ์ ๋ ํด๋น ์์ฒญ์ ํค๋์ origin ํค๋๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํ๋ฉฐ, ๊ทธ ๊ฐ์http://www.abc.com
์ด ๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ณดํต ์๋ฒ์๊ฒ ๋ค์ด์ค๋ ์์ฒญ๋ค์ ๋ธ๋ผ์ฐ์ ์์๋ง ์ค๋๊ฒ ์๋๋ค. ์๋ฒ๋ผ๋ฆฌ๋ ์๋ก ์์ฒญ์ ํ๋ค.
๋ธ๋ผ์ฐ์ ๋ฅผ ํตํ์ง ์์ ์๋ฒ๊ฐ ํต์ ์ผ ๊ฒฝ์ฐ Origin ํค๋๋ ์๋์ผ๋ก ๋ถ๋๊ฒ ์๋๋ค. ๊ทธ๋ ๋ค๊ณ ๋ชป๋ถ์ด๋ ํ๋ฉด ๊ทธ๊ฒ๋ ์๋๋ค. ์๋ฒ๊ฐ ํต์ ์ผ๋ ์์ฒญ์ ์๋ฒ๋ ์ํ๋ฉด Origin ํค๋๋ฅผ ์ ๋ฃ์ด๋ ๋๊ณ , ๋ฃ๊ณ ์ถ์ผ๋ฉด Origin์ ๊ฐ์ผ๋ก ์๋ฌด ๋ฌธ์์ด์ด๋ ๋ง์๋๋ก ๋ฃ์ด์ ๋ณด๋ผ ์ ์๋ค.์ฆ ์๋ฒ๊ฐ ์์ฒญ ์ํฉ์์ CORS์ ์ฑ ์ ๋ณด์์ ์๋ฏธ๋ฅผ ๊ฐ์ง์ง ์๋๋ค.
์๋ฒ๊ฐ ํน์ ์์ฒญ์์๊ฒ๋ง ์์ฒญ์ ํ์ฉํด์ผ ํ ๋, ์ธ์ฆํ ํฐ์ด๋ ๋ณด์ํค ๋ฑ ๋ ํ์คํ๊ณ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋ง์ผ ์ด๋ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ค์ ์ ํตํด, CORS ์๋ฌ๋ฅผ ์ฐํํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด, ๊ทธ๊ฑด ๋ธ๋ผ์ฐ์ ๋ณด์ ์ทจ์ฝ์ ์ด๋ค. ํ๋ก ํธ์๋ ์์ค์ฝ๋๋ง์ผ๋ก CORS ์๋ฌ๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ์ ์์ด์ผ ํ๋ค.
๋ง์ฝ ์ด๋ ํ ํ๋ก ํธ์๋ ๊ธฐ์ ๋ง์ผ๋ก CORS ์๋ฌ๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ์ ๋ฐ๊ฒฌํ๋ค๋ฉด, ๋ฐ๋์ ํด๋น ๋ธ๋ผ์ฐ์ ๋ฅผ ๊ฐ๋ฐํ ๊ธฐ์ ๋๋ ์คํ์์ค ์ปค๋ฎค๋ํฐ์ ์๋ ค์ฃผ์. ์ทจ์ฝ์ ์ ์ฐพ์์คฌ๋ค๋ฉฐ ๊ณ ๋ง์ํ ๊ฒ์ด๋ค.
์ํฉ์๋ฐ๋ผ ์ต์ ์ ๋์ฒํ๋ ๋ฐฉ๋ฒ์ด ๋ค ๋ค๋ฅด๋ค.
์ด ๋ฐฉ๋ฒ์
๊ทธ๋ฆฌ๊ณ
๊ฐ์ฅ ์ ํฉํ ๋ฐฉ๋ฒ์ด๋ค.
๋ฐฑ์๋ ๋ง ์ธํ
ํ์๋ ๋ฐฑ์๋๊ฐ๋ฐ์๊ฐ ์ค์๋ก CORS ๊ด๋ จ ์ค์ ์ ๊น๋จน์ ๋๊ฐ ์๋ค. (๋๋ ์์ฃผ ๊ทธ๋ฐ๋ค)
๋ฐฑ์๋ ๊ฐ๋ฐ์์๊ฒ ํ ์ํฉ์ ๋งํด์ฃผ๋ฉด ๋์ ํ๋ฅ ๋ก ๊ฐ์ค๋ฒจ๋ธ ์ ์ ๊ทธ๊ณ ์ง ๋์จ ์ฌ๋๋ง๋ฅ "์! ๋ง๋ค"๋ฅผ ์ฐ๋ฐํ๋ฉฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์์ ๋ชจ์ต์ ๋ณด๊ฒ ๋ ๊ฒ์ด๋ค.
์ด ๋ฐฉ๋ฒ์
create-react-app
๋๋ vue-cli
์ ๊ฐ์ ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ณต์ ํ๋ก์ ํธ ์ธํ
ํด์ ํตํด ์ธํ
ํ์ ๋์ ํฉํ๋ค.
๋, ๋ฆฌ์กํธ ํ์ ์ผ๋ก ์ถ๊ฐ ์กฐ๊ฑด์ด ๋ ์๋๋ฐ (vue๋ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค.)
cors ์๋ฌ๊ฐ ๋ฐ์ํ๋ api๊ฐ, ๋ด๊ฐ ์ฃผ๋ก ์ฐ๊ฒ ๋ api ์ผ๋ ์ฌ์ผ ํ๋ค.
(์ฆ ์ฌ๋ฌ๊ฐ์ง ํ๋ก ํธ์๋์์ ์ธ๋ถ api ์ฌ๋ฌ๊ฐ๋ฅผ ์์ด์ฐ๋๋ฐ, ๋ค๋ค cors๊ฐ ๋๋ ์ํฉ์ ์๋์ด์ผ ํ๋ค๋ ๊ฒ)
๊ณต์๋ฌธ์: https://create-react-app.dev/docs/proxying-api-requests-in-development
package.json ์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ค.
ํ
์คํธ ํ๋๋์ ์ฌ์ฉํ ํ
์คํธ์ฉ api ์๋ฒ์ ๋๋ฉ์ธ์ ์๋ ์ฝ๋์ http://my-api-server.com
๋ผ ์จ์๋ ๋ถ๋ถ์ ๋์
ํด์ ์ฐ์
"proxy": "http://my-api-server.com"
๊ณต์๋ฌธ์: https://cli.vuejs.org/config/#devserver-proxy
vue.config.js ํ์ผ์ (๋ง์ฝ ์ด ํ์ผ์ด ์๋ค๋ฉด, package.json ๊ณผ ๊ฐ์ ๊ฒฝ๋ก์ ๋ง๋ค์)
๋ค์๊ณผ๊ฐ์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์
module.exports = {
devServer: {
proxy: 'http://my-api-server.com'
}
}
์ฌ๋ฌ๊ฐ์ api ์๋ฒ์ ๋ํด ์ฒ๋ฆฌ๋ฅผ ํด์ค์ผ ํ๋ค๋ฉด, ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ฉด์ ์กฐ๊ธ ๋ ์ค์ ์ ์ปค์คํ ํด์ฃผ๋ฉด ๋๋ค.
์ด ๋ฐฉ๋ฒ์ ์์ ๋ฐฉ๋ฒ๋ค์ด ํตํ์ง ์์๋ ํ ์ ์๋ ์ตํ์ ๋ฐฉ๋ฒ์ด๋ค.
๋ชจ๋ ์ํฉ์ ๋ํด ์๋ฒฝํ๊ฒ ๋ง์ถค ๋์์ด ๊ฐ๋ฅํ์ง๋ง ์น๋ช
์ ์ธ ๋จ์ ์ด ํ๋ ์๋ค.
๋ฐ๋ก ๋น์ ์ด ๋ฐฑ์๋๋ฅผ ๋ง์ง ์ค ์์์ผ ํ๋ค๋ ๊ฒ
๊ธ ์์ชฝ์์, ์๋ฒ๊ฐ ํต์ ์ CORS์ ์ํฅ์ ์๋ฐ๋๋ค๊ณ ์จ๋๊ฒ ๋๋ชฉ์ด ์์๋ค. (์๋ฌด๋ ์์ฝ์๊ฒ ์ง๋ง)
api ์๋ฒ๋ก๋ถํฐ ๋ฐ์์ผ ํ ์์ฒญ์ ๋์ ์์ฒญํด์ ํ๋ก ํธ์๋์ ์๋ตํด์ฃผ๋ ์๋ฒ๋ฅผ ๊ฐ๋ฐํ๊ฒฝ์ ๋ง๋ค์ด๋๊ณ , cors ์ ์ฑ ์ ๋ด ๋ง๋๋ก ์ฃผ๋ฌด๋ฅธ ๋ค, ๊ฐ๋ฐ๊ณผ์ ๋์ api์์ฒญ์ ๊ฑฐ๊ธฐ๋ก ๋ณด๋ด๋ฉด ๋๋ค.
ํ๋ก ํธ์๋์ ๋จธ๋ฆฌ๋ฅผ ์ฅ์ด๋ฏ๊ฒ ๋ง๋ค๊ณ ๋ฐฑ์๋๋ฅผ ๊ท์ฐฎ๊ฒ ๋ง๋๋ ์ํ์ธ๋ฐ๋ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ๋ฒค๋๋ค์ด ์ด์ฌํ ์ด ๋ช ์ธ๋ฅผ ๋ง๋ค๊ณ ๊ด๋ฆฌํ๊ณ ๋ฐ๋ฅด๋ ๋ฐ์๋ ์ด์ ๊ฐ ์๋ค. ํ๊ด๋ฌธ ๋์ด๋ฝ ๋งค๋ฒ ์ฌ๋๊ฒ ๊ท์ฐฎ๋ค๊ณ ์๋ฌด๋ ๋์ด๋ฝ์ ๋ฏ์ด๋๊ณ ์ด์ง ์๋๋ค.
์์ ์ธ๊ธํ๋, CORS๋ฅผ ๋นํ์ฑํํด๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฐ๋ ๋ฐฉ๋ฒ ์ญ์ ์ข์ ๋์ฒ๋ฒ์ด ์๋๋ค.
๋ธ๋ผ์ฐ์ ์์ CORS๋ฅผ ๋นํ์ฑํ ํด์ ํ๋ก ํธ์๋์์ API๋ฅผ ๋ถ์ด๋ฉด, ๋๋ CORS ์๋ฌ๋ฅผ ์๊ฒช๊ฒ ์ง๋ง, ์ผ๋ฐ์ ์ธ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฐ๋ ์ฌ๋๋ค์๊ฒ, ๋ค์ ๋งํด ๋๋ฅผ ์ ์ธํ ๋ชจ๋ ์ฌ๋๋ค์๊ฒ ์ฌ์ ํ ์๋ฌ๊ฐ ๋๊ณ ์๋๊ฑฐ๋ค.
๊ฐ๋ฐํ๊ฒฝ์์๋ง CORS ์๋ฌ๊ฐ ๋ฐ์ํ๊ณ ์๋๊ฑฐ๋ผ๊ณ ํ์ ํ ์ ์๋ค๋ฉด ๋ชจ๋ฅด๊ฒ ์ง๋ง, ์คํ ์ด์ง/ํ๋ก๋์ ํ๊ฒฝ ํ ์คํธ ํ ๋ CORS ๋ฌธ์ ๊ฐ ๋๋๋ผ๋ ์์์ฑ๊ธฐ๊ฐ ์ด๋ ค์์ง๊ฒ ๋๊ณ , ํ๋ก๋์ ๋ฐฐํฌํ ์ฅ์ ๋ฅผ ๊ฒช์ ๊ฐ๋ฅ์ฑ์ด ์๊ธด๋ค.
๋ผ๊ณ ์๊ฐํ๋ ์ฌ๋๋ค์ด ์์๊ฒ ๊ฐ์์, nodeJS๋ก ๋ง๋ ๊ฐ๋จํ ํ๋ก์ ์๋ฒ๋ฅผ ์ง์ ๋ง๋ค์ด๋ดค๋ค.
https://github.com/joonseokhu/api-proxy-server
๊ธํ๊ฒ ๋ง๋ ๊ฑฐ๋ผ ์ด๋จ์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง, ํ๋ช ์๊ฒ๋ผ๋ ๋์์ด ๋์์ผ๋ฉด ํ๋ค.
์ ๋ CORS๋๋ฌธ์ ๋ง๋ ํ๋ก์ ์๋ฒ๊ฐ ์์ต๋๋ค.
https://cors-proxy.org/
์ค์ฐ ์ ์ง๋ด์์ฃ ?