CORS
CORS๋?
SOP์ ์๋๋ฆฌ์ค์ CORS ์๋๋ฆฌ์ค๋ฅผ ์ค๋ช
ํ ์ฌ์ง
- Cross-Origin Resource Sharing (๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ )
- ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ดํ๋ฆฌ์ผ์ด์
์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์
- ์ถ์ฒ๋ ๋๋ฉ์ธ, ํ๋กํ ์ฝ, ํฌํธ๊ฐ ๋ชจ๋ ๋์ผํจ์ ๋ปํจ
- ๋ธ๋ผ์ฐ์ ์์๋ ๋์ผ ์ถ์ฒ ์ ์ฑ
(SOP) ๋ก ์ธํด ๋ค๋ฅธ ์ถ์ฒ ๊ฐ ์์(๋ฐ์ดํฐ) ์ด๋์ด ๊ธ์ง
SOP (Same-Origin Policy)
CORS๋ฅผ ์์๋ณด๊ธฐ ์ ๋จผ์ SOP์ ๋ํด ์์๋ณด์
- ๊ต์ฐจ ์ถ์ฒ ์ ์ฑ
์ผ๋ก ์ด๋ค ์ถ์ฒ์์ ๋ถ๋ฌ์จ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค์ ์ํธ์์ฉํ๋ ๊ฒ์ ์ ํํจ
- XMLHttpRequest(fetch() ์ ๊ฐ์)์์๋ฅผ ์ฌ์ฉํ ๋ ์ํธ์์ฉ์ ํต์
- Chrome์ ๊ฐ๋ฐ์ ๋๊ตฌ์์ Fetch/XHR ํญ๋ชฉ
SOP, CORS์์ Origin (์ถ์ฒ) ์ด๋?
- ์ถ์ฒ๋ Protocol, Host, Port๊ฐ ๋ชจ๋ ๋์ผํ ๋ ๋์ผ ์ถ์ฒ๋ผ๊ณ ํ๋ค.
- ์์ ์์์์ https๋ 443ํฌํธ๋ฅผ ์ฌ์ฉํจ์ผ๋ก ์๋ต ๊ฐ๋ฅํ๋ค.
https://velog.io:443/@k-moovie
๋ ๋์ผ ์ถ์ฒ์ด๋ค
CORS๋?
-
์น ๊ธฐ์ ์ด ๋ฐ์ ํจ์ ๋ฐ๋ผ ๋ธ๋ผ์ฐ์ ์์ ๋ค๋ฅธ ์ฌ์ดํธ์ ์์(์ด๋ฏธ์ง์ ๊ฐ์)์ ์์ฒญํ ์ ์๋ค.
-
๊ธฐ๋ณธ์ ์ผ๋ก ์น ํด๋ผ์ด์ธํธ ์ดํ๋ฆฌ์ผ์ด์
์ด ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ๋๋ HTTP ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ request๋ฅผ ๋ณด๋ธ๋ค
-
์ด ๋ ๋ธ๋ผ์ฐ์ ๋ request header
์ Origin
ํ๋์ ์์ฒญ์ ๋ณด๋ด๋ ์ถ์ฒ๋ฅผ ํจ๊ป ๋ด์ ๋ณด๋ธ๋ค.
Origin: https://velog.io/@k-moovie
-
์ดํ ์๋ฒ์์ ์๋ต์ ๋ณด๋ผ ๋ response header
์ Access-Control-Allow-Origin
ํ๋์ '์ด ๋ฆฌ์์ค๋ฅผ ์ ๊ทผํ๋ ๊ฒ์ด ํ์ฉ๋ ์ถ์ฒ'๋ฅผ ์ ์กํ๋ค.
-
๋ธ๋ผ์ฐ์ ๋ ์์ ์ด ๋ณด๋ธ Origin
๊ณผ ์๋ฒ์์ ์จ ์๋ต์ Access-Control-Allow-Origin
๋ฅผ ๋น๊ตํด ๊ฐ๋ค๋ฉด ํ์ฉํ๋ค.
CORS์ ๋ค์ํ ์๋๋ฆฌ์ค
Preflight Request
- ์ผ๋ฐ์ ์ผ๋ก ์น ์ดํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฐํ ๋ ํํ ๋ง์ฃผํ๋ ์๋๋ฆฌ์ค
- ์๋น ์์ฒญ๊ณผ ๋ณธ ์์ฒญ์ผ๋ก ๋ ๋ฒ ์ ์ก
OPTIONS https://velog.io/@k-moovie
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ko;q=0.8,ja;q=0.7,la;q=0.6
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: GET
Connection: keep-alive
Host: velog.io
Origin: https://velog.io
Referer: https://velog.io/@k-moovie/user
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
- ์๋น ์์ฒญ์ method๊ฐ OPTIONS๋ก ์ ์ก๋๋ค
- ๋ณธ ์์ฒญ์ ์ฌ์ฉํ ๋ค๋ฅธ ์ ๋ณด๋ฅผ (method, header ๋ฑ) ๊ฐ์ด ์ ์กํ๋ค.
OPTIONS https://velog.io/@k-moovie 200 OK
Access-Control-Allow-Origin: https://velog.io
Content-Encoding: gzip
Content-Length: 699
Content-Type: text/xml; charset=utf-8
Date: Sun, 24 May 2020 11:52:33 GMT
P3P: CP='ALL DSP COR MON LAW OUR LEG DEL'
Server: Apache
Vary: Accept-Encoding
X-UA-Compatible: IE=Edge
- ์๋ฒ๋ ์๋น ์์ฒญ์ ์๋ต์ผ๋ก Access-Control-Allow-Origin์ ๋ฐํํ๋ค.
Simple Request
- ์๋ฒ์ ๊ณง๋ฐ๋ก ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ผ๋ก ์๋ฒ๋ ๋ค๋ฅธ ์ถ์ฒ์ ์์ฒญ์ ๊ฐ๋ฆฌ์ง ์์ผ๋ฏ๋ก ์ฌ์ฉ ์ ์ฃผ์๊ฐ ํ์ํ๋ค
- Preflight Request์์ ์๋น ์์ฒญ์ ์ ๊ฑฐํ ๊ฒ
- ์๋์ ์ ํ ์ฌํญ์ด ์๋ค
- ์์ฒญ์ ๋ฉ์๋๋
GET, HEAD, POST
์ค ํ๋์ฌ์ผ ํ๋ค.
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
๋ง ํ์ฉ๋๋ค.
Credentialed Request
- ๋ค๋ฅธ ์ถ์ฒ ๊ฐ ํต์ ์์ ์ข ๋ ๋ณด์์ ๊ฐํํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ ๋น๋๊ธฐ ๋ฆฌ์์ค ์์ฒญ API์ธ XMLHttpRequest ๊ฐ์ฒด๋ fetch API๋ ๋ณ๋์ ์ต์
์์ด ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค ์ ๋ณด๋ ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ํค๋๋ฅผ ํจ๋ถ๋ก ์์ฒญ์ ๋ด์ง ์๋๋ค
- ์์ฒญ์ ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ๋ด์ ์ ์๊ฒ ํด์ฃผ๋ ์ต์
์ด ๋ฐ๋ก credentials ์ต์
- ์๋์ ๊ฐ์ ์ ํ ์ฌํญ์ด ์๋ค
Access-Control-Allow-Origin
์๋ *
๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ช
์์ ์ธ URL์ด์ด์ผํ๋ค.
- ์๋ต ํค๋์๋ ๋ฐ๋์
Access-Control-Allow-Credentials: true
๊ฐ ์กด์ฌํด์ผํ๋ค.
๋ ์์๋ณด๊ธฐ
Spring์์ CORS๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
- Servlet Filter๋ฅผ ์ฌ์ฉํ์ฌ ์ปค์คํ
ํ Cors ์ค์
- WebMvcConfiguer๋ฅผ ๊ตฌํํ Configuration ํด๋์ค๋ฅผ ๋ง๋ค์ด์ addCorsMappings()๋ฅผ ์ฌ์ ์
- Spring Security์์ CorsConfigurationSource๋ฅผ Bean์ผ๋ก ๋ฑ๋กํ๊ณ config์ ์ถ๊ฐ
Reference