CORS(Cross-Origin Resource Sharing) ๐
์น ๋ณด์ ์ ์ฑ
์ค Same-Origin Policy
๋ ํ ์ถ์ฒ(Origin)์์ ๋ก๋๋ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ ์์๊ณผ ์ํธ์์ฉํ์ง ๋ชปํ๋๋ก ์ ์ฝํ๋ค. ์ธ๊ธํ ์ถ์ฒ(Origin)
๋ ๋ ํ์ด์ง์ ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ๊ฐ ๊ฐ์ผ๋ฉด ๋์ผ ์ถ์ฒ๋ก ๊ฐ์ฃผํ๋ค.
ํ์ง๋ง ์ด๋ฌํ ๋ณด์ ์ ์ฑ
์ผ๋ก ์ธํด ํ ์ฌ์ดํธ๋ก๋ถํฐ ๋ฐ์์ค๋ ๋ฆฌ์์ค๋ ์น ํฐํธ, CDN ๋ฑ์ ์ฌ์ฉ์ ๋ฌธ์ ๊ฐ ๋๊ณ ์์ด CORS(Cross-Origin Resource Sharing)
์ด๋ผ๋ ์ถ๊ฐ ์ ์ฑ
์ด ๋์ค๊ฒ ๋์๋ค.
CORS ์์ฒญ ๐
CORS ์์ฒญ์๋ Simple/Preflight, Credential/Non-Credential์ ์กฐํฉ์ผ๋ก ์ด 4๊ฐ์ง ์์ฒญ์ด ์กด์ฌํ๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฒญ ๋ด์ฉ์ ๋ถ์ํ์ฌ 4๊ฐ์ง ๋ฐฉ์ ์ค ํด๋นํ๋ ๋ฐฉ์์ผ๋ก ์๋ฒ์ ์์ฒญ์ ๋ ๋ฆฌ๋ฏ๋ก ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ชฉ์ ์ ๋ง๋ ๋ฐฉ์์ ์ ํํด ๊ทธ ์กฐ๊ฑด์ ๋ง๊ฒ ์ฝ๋ฉํด์ผ ํ๋ค.
Simple Requests ๐
๋ช๋ช ์์ฒญ(Request)๋ค์ CORS preflight๋ฅผ ํธ๋ฆฌ๊ฑฐํ์ง ์๋๋ค. MDN
์๋ฃ์ ํฐ๋งฅ์ค ์ถ์ฒ์๋ฃ์์๋ ์ด๋ฅผ ๋๊ณ Simple Requests
๋ผ๊ณ ๊ตฌ๋ถํ์ง๋ง CORS๋ฅผ ์ ์ํ ์ค์ Fetch ์คํ์์๋ Simple Requests๋ผ๋ ์ฉ์ด๋ฅผ ์ฌ์ฉํ์ง ์๋๋ค. CORS preflight๋ฅผ ํธ๋ฆฌ๊ฑฐ ํ์ง ์๋ ์์ฒญ(ํธ์์ MDN์์ ‘simple requests’๋ผ๊ณ ๋ช
๋ช
ํ๋)์ ์๋์ ์กฐ๊ฑด๋ค์ ๋ชจ๋ ๋ง์กฑํ๋ ์์ฒญ์ ๊ฐ๋ฆฌํจ๋ค.
- GET/POST/HEAD ๋ฉ์๋๋ง์ ์ฌ์ฉํด์ผ ํ๋ค.
- User Agent์ ์ํด ์๋์ผ๋ก ์ค์ ๋ ํค๋, Fetch ์คํ์์ “forbidden header name"์ด๋ผ๊ณ ์ ์๋ ํค๋๋ค์ ์ ์ธํ๊ณ “CORS-safelisted request-header”๋ผ๊ณ Fetch ์คํ์ ์ ์๋ ์๋์ ํค๋๋ง์ด ์ง์ ์ ์ผ๋ก ์์ฒญ ์์ ์ค์ ๋ ์ ์๋ค.
- Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type์ด ์๋ ์ค ํ๋์ฌ์ผ ํ๋ค.
- application/x-www-form/urlencoded
- multipart/form-data
- text/plain (๋ฐ๋ก ์ง์ ํ์ง ์์ ์์ default)
- Request ์์
ReadableStream
๊ฐ์ฒด๊ฐ ์์ด์ผ ํ๋ค. - ์์ฒญ ์์ ์๋
XMLHttpRequestUpload
๊ฐ์ฒด์ ๋ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์์ด์ผ ํ๋ค. (ํด๋น ๊ฐ์ฒด๋ XMLHttpRequest.upload ํ๋กํผํฐ๋ฅผ ์ด์ฉํด ์ ๊ทผ ๊ฐ๋ฅํ๋ค.)
์ด๋ฌํ Simple Request ๋ฐฉ์์์ ํด๋ผ์ด์ธํธ๋ ์๋ฒ๋ก ์์ฒญ์ ํ ๋ฒ ๋ณด๋ด๊ณ , ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ฒ๋ ํ์ ์ ํ ๋ฒ ๋ณด๋ด๋ ๊ฒ์ผ๋ก ์์ฒญ์ ๋ํ ์๋ต์ด ์ข ๋ฃ๋๋ค.
์๋๋ Simple requests๋ฅผ ์ฌ์ฉํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ ์ด๋ค. ์๋ ์ฝ๋๊ฐ http://foo.example
์๋ฒ๋ก๋ถํฐ ์ ๊ณต๋์ด http://bar.other
๋ผ๋ ์ธ๋ถ ๋๋ฉ์ธ์ผ๋ก๋ถํฐ ๋ฆฌ์์ค๋ฅผ ๋ฐ์์ค๋ ค ํ๋ค๋ ์ํฉ์ ๊ฐ์ ํด๋ณด์.
์ ์ฝ๋๋ฅผ ํตํด ์น ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ๋ก Request๋ฅผ ๋ณด๋ด๊ณ ์๋ฒ๋ก๋ถํฐ Response๋ฅผ ๋ฐ๋ ๊ณผ์ ์ ์๋์ ๊ฐ์ด ๊ฐ๋ตํ๊ฒ ๋ํ๋ผ ์ ์๋ค.
์ด ๋, ์ค์ Request์ Response๊ฐ ์ด๋ค ์์ผ๋ก ์ค๊ณ ๊ฐ๋์ง ์๋ ํ
์คํธ๋ฅผ ๋ณด์. Request์ Origin
, Response์ Access-Control-Allow-Origin
๋ถ๋ถ์ ์ค์ฌ์ผ๋ก ์ดํด๋ณด์.
|
|
๋จผ์ , ์๋ ์์ ์ฝ๋๊ฐ ์๋ฒ๋ก ๋ณด๋ด๋ Request๋ฅผ ๋ํ๋ด๋ฉฐ Origin ํค๋๋ถ๋ถ์ ์ปจํ
์ธ ๊ฐ http://foo.example
๋ก๋ถํฐ ์ค๋ ๊ฒ์ด๋ผ๊ณ ์๋ฒ์๊ฒ ์๋ฆฌ๋ ์ญํ ์ ํ๋ค.
์๋ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด๋ Response๋ฅผ ๋ํ๋ด๋ฉฐ, Access-Control-Allow-Origin: *
์ ๋ชจ๋ ๋๋ฉ์ธ์ cross-site ๋ฐฉ์์ผ๋ก๋ถํฐ ์ก์ธ์ค๊ฐ ๊ฐ๋ฅํ๋ค๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ฆฌ๋ ์ญํ ์ ํ๋ค. ํ์ง๋ง ๋ง์ฝ ์ด ํค๋๊ฐ
|
|
์ฒ๋ผ ์๋ค๋ฉด http://foo.example
์ ์ ์ธํ ๋ค๋ฅธ ๋๋ฉ์ธ๋ค์์๋ cross-site ๋ฐฉ์์ผ๋ก ํด๋น ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
Preflighted Requests ๐
Simple Requests
์ ๋ค๋ฅด๊ฒ “preflighted” requests(์ฌ์ ์ ๋ฌ ์์ฒญ)๋ ๋จผ์ OPTIONS
๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ HTTP request๋ฅผ ๋จผ์ ๋ณด๋ด ์ค์ ์์ฒญ์ด ๋ณด๋ด๊ธฐ์ ์์ ํ์ง ํ์ธํ๋ค. ์๋ ์กฐ๊ฑด๋ค ์ค ํ๋๋ผ๋ ๋ง์กฑํ๋ฉด Preflighted Requests
๋ก ๊ฐ์ฃผํ๋ค.
- Request๊ฐ ์๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
Simple requests
์ ๋ง์ฐฌ๊ฐ์ง๋ก User Agent์ ์๋ ์ค์ ๋ ํค๋๋ฅผ ์ ์ธํ๊ณ , “CORS-safelisted request-header"๋ฅผ ํฌํจํ๋ค.- Accept
- Accept-Language
- Content-Language
- Content-Type
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type ํค๋ ๊ฐ์ด ์๋๋ฅผ ์ ์ธํ ๋ค๋ฅธ ๊ฐ์ธ ๊ฒฝ์ฐ
- application/x-www-form-url
- multipart/form-data
- text/plain
- Request ์์ ์๋
XMLHttpRequestUpload
๊ฐ์ฒด์ ํ ๊ฐ ์ด์์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๋ฑ๋ก๋ ๊ฒฝ์ฐ ReadableStream
์ด Request ์์์ ์ฌ์ฉ๋ ๊ฒฝ์ฐ
์๋๋ preflighted ์์ฒญ์ ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ์์ ์ด๋ค.
|
|
์ ์์ ์ฝ๋์์๋ XML body๋ฅผ ๋ณด๋ด๊ธฐ ์ํด POST
๋ฐฉ์์ ์ฌ์ฉํ๊ณ X-PINGOTHER: pingpong
์ด๋ผ๋ customized request ํค๋๋ฅผ ์ฌ์ฉํ๋ค. ๋ํ, application/xml
Content-Type์ ์ฌ์ฉํจ์ผ๋ก์จ ์์์ ๋ช
์๋ 3๊ฐ์ง Content-Type ์ธ์ ํด๋นํ์ฌ ํด๋น request๊ฐ preflighted
ํ์
์ด๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
์ด์ , ์ด preflighted request
๊ฐ ์๋ฒ๋ก ๋ณด๋ด์ง ๋ ์ด๋ค ์์ผ๋ก ์์ฒญ๊ณผ ์๋ต์ด ์ค๊ณ ๊ฐ๋์ง ์๋ ๊ทธ๋ฆผ์ ํตํด ๊ฐ๊ด์ ์ผ๋ก ์ดํด๋ณด์.
์ ๊ทธ๋ฆผ์์ ์ฃผ์ํด์ผํ ๊ฒ์ ์๋์ ์ค์ REQUEST/REPONSE ์ฝ๋์์ ๋ณด๊ฒ ์ง๋ง ์ค์ POST request ์์๋ Access-Control-Request-*
ํค๋๊ฐ ์๋ค๋ ์ ์ด๋ค. ํด๋น ํค๋๋ค์ ๋ชจ๋ OPTIONS
request์์๋ง ํ์ํ๋ค. ๋ํ, preflighted request์ ๊ฒฝ์ฐ ๋ฉ์ธ Request๋ฅผ ๋ณด๋ด๊ธฐ ์ ์ Preflighted Request๋ฅผ ํ๋ฒ ๋ ๋ณด๋ธ๋ค๋ ์ ์ด ์ฃผ์ํ์.
์๋๋ ์ ๋ค์ด์ด๊ทธ๋จ์ ๋ํ ์ค์ Request & Response ๋ด์ฉ์ด๋ค.
|
|
๋จผ์ , preflighted request
์ ๊ทธ ์๋ต์ ๋ํด ์ดํด๋ณด์. Access-Control-Request-Method
ํด๋๋ ์๋ฒ์๊ฒ ์ค์ Request๊ฐ ๋ณด๋ด์ก์ ๋ ํด๋น Request์ ๋ฉ์๋์ X-PINGOTHER, Content-Type
๋ฑ์ custom header๋ค์ ํจ๊ป ์ ์กํ ๊ฒ์ด๋ผ๊ณ ๋ฏธ๋ฆฌ ์๋ฆฐ๋ค. ์๋ฒ๋ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ด๋ฌํ ์ ๋ณด๋ฅผ ๋ฏธ๋ฆฌ preflighted request
๋ฅผ ํตํด ์ ๋ฌ๋ฐ๊ณ ์ค์ request๋ฅผ ๋ฐ์ ๊ฒ์ธ์ง๋ฅผ ๊ฒฐ์ ํ ๋ค ์๋ ค์ค๋ค. ์์ ๋ํ๋ Reponse ์ฝ๋ ์ค ์ ์ฌํด์ผํ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ๋ค.
์๋ฒ๋ preflighted request์ ๋ํ ์๋ต์ ํตํด ํด๋ผ์ด์ธํธ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ์๋์ ํค๋, ๊ทธ๋ฆฌ๊ณ ํด๋น ๋ฆฌ์์ค ์ ๊ทผ์ ์ํด ํ์ฉ๋ origin์ http://foo.example
๋ก ์ ํํ์ฌ ๋ณด๋ด์ฃผ๊ณ ์๋ค. ๋ง์ง๋ง์ผ๋ก Access-Control-Max-Age
๋ ํด๋น reponse๊ฐ ๋๋ค๋ฅธ preflight request๋ฅผ ๋ณด๋ด์ง ์๊ณ ์ผ๋ง ๋์ ์บ์๋์ด ์๋์ง๋ฅผ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ ค์ฃผ๋ ์ญํ ์ ํ๋ค. ์ฌ๊ธฐ์ 86400์ 86400์ด๋ฅผ ๋ํ๋ด์ด 24์๊ฐ๋์ cached response๊ฐ ์ ํจํ๋ค๊ณ ์๋ฆฐ๋ค.
|
|
Requests with credentials ๐
๋ง์ง๋ง์ผ๋ก Credential, Non-Credential์ ๊ตฌ๋ถํ CORS Request ์ข ๋ฅ์ ๋ํด ๊ธฐ์ ํ๋ค. ์ด “credentialed” requests๋ HTTP Cookie์ HTTP Authentication information์ ์ทจ์ฝ์ ์ ๋๋นํ์ฌ ๋ง๋ค์ด์ง request ํ์ ์ด๋ค. ๊ธฐ๋ณธ์ผ๋ก ์น ๋ธ๋ผ์ฐ์ ๋ cross-site XMLHttpRequest์ Fetch invocation์์ credential์ ๋ณด๋ด์ง ์๋๋ค.
์๋ ์ฝ๋๋ฅผ ์๋ก ๋ค์ด๋ณด์. http://bar.other/
๋ก๋ถํฐ ๋ฐ์ ์ปจํ
์ธ ๊ฐ ์ฟ ํค๋ฅผ ์ค์ ํ๋ ๋ฆฌ์์ค๋ผ๊ณ ๊ฐ์ ํ๊ณ , ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๊ฐ http://foo.example
๋ด์์ ๋์ํ๋ ์ฝ๋๋ผ๊ณ ์๊ฐํ์.
|
|
์์ฒ๋ผ ์๋ก ๊ฐ์ ธ์ฌ ์ปจํ
์ธ ์์ ์บ์๋ฅผ ์ค์ ํ๋ ๋ฑ์ ํ์๋ฅผ ํ ๋ ๋ฐ๋์ withCredentials
๋ฅผ ์ค์ ํด์ค์ผ ํ๋ฉฐ, ํด๋น ํค๋๊ฐ ์ค์ ๋์๋ค๋ฉด ์น ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ response ์์ Access-Control-Allow-Credentials: true
๊ฐ ์๋ ๊ฒฝ์ฐ๋ ๋ชจ๋ ๊ฑฐ์ ํด๋ฒ๋ฆฐ๋ค.