๐ ๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy, SOP)
๋ธ๋ผ์ฐ์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก SOP ์ ์ฑ ์ ๋ฐ๋ฅด๊ณ ์๋ค.
SOP๋ 2011๋ RFC 6454์์ ๋ฑ์ฅํ ๋ณด์ ์ ์ฑ ์ผ๋ก "๊ฐ์ ์ถ์ฒ์์๋ง ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ ์ ์๋ค"๋ผ๋ ๊ท์น์ ๊ฐ์ง ์ ์ฑ .
SOP์ ๋ฑ์ฅ๋ฐฐ๊ฒฝ์ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๋ณด์ ๊ฐํ:
- XSS (Cross-Site Scripting) ๋ฐฉ์ง: ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์ ์ฑ ์คํฌ๋ฆฝํธ๊ฐ ์ฌ์ฉ์ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋์ด ๋ค๋ฅธ ์ฌ์ดํธ์ ๋ฐ์ดํฐ๋ฅผ ํ์น๊ฑฐ๋ ์กฐ์ํ๋ ๊ฒ์ ๋ฐฉ์ง.
- CSRF (Cross-Site Request Forgery) ๋ฐฉ์ง: ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉ์์ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ด์ฉํด ๋ค๋ฅธ ์ฌ์ดํธ์ ๋ฌด๋จ์ผ๋ก ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ ๋ง๋๋ค.
2. ๋ฐ์ดํฐ ๋ณดํธ:
- ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ข ์ข ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ๋ค. ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ํ ์ฌ์ดํธ์ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ฌ์ดํธ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ฒ์ ์ ํํจ์ผ๋ก์จ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ค.
3. ์ ๋ขฐํ ์ ์๋ ํต์ :
- ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์น ๋ธ๋ผ์ฐ์ ๊ฐ ํน์ ์ถ์ฒ์์๋ง ์์์ ์์ฒญํ๊ณ ์๋ต์ ๋ฐ์ ์ ์๋๋ก ํจ์ผ๋ก์จ, ํต์ ์ ์ ๋ขฐ์ฑ์ ๋์ธ๋ค. ์ด๋ ํนํ AJAX ์์ฒญ์์ ์ค์.
4. ํ์คํ:
- ์น ๋ณด์ ํ์คํ์ ์ผํ์ผ๋ก, ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ๋ธ๋ผ์ฐ์ ์ ์น ๊ฐ๋ฐ์ ๊ฐ์ ๊ณตํต๋ ๋ณด์ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํ๋ค. ์ด๋ฅผ ํตํด ๋ณด์ ๊ด๋ จ ํผ๋์ ์ค์ด๊ณ , ์ผ๊ด๋ ๋ณด์ ์ ์ฑ ์ ์ ์งํ ์ ์๋ค.
์ฃผ๋ ์ด์ ๋ ์น ๋ณด์์ด๋ฉฐ XSS, CRSF ๊ณต๊ฒฉ์ ๋ํด์๋ ๋ค์ ๊ธ์์ ์ค๋ช ์์ .
๐ ์ถ์ฒ (Origin)
SOP์์ ๋งํ๋ '๊ฐ์ ์ถ์ฒ'๋ ๋ฌด์์ ์๋ฏธํ ๊น?
์น์์ ๋งํ๋ ์ถ์ฒ (Origin)๋ URL์ ์คํค๋ง(ํ๋กํ ์ฝ), ํธ์คํธ(๋๋ฉ์ธ), ํฌํธ ์ด 3๊ฐ์ง๋ก ์ ์๋๋ค.
๋์ผ ์ถ์ฒ ์์
- http://example.com/hello ์ http://example.com/bye → ํ๋กํ ์ฝ, ๋๋ฉ์ธ, ํฌํธ๊ฐ ๋ชจ๋ ๊ฐ์ผ๋ฏ๋ก ๋์ผ ์ถ์ฒ์ด๋ค.
- http://example.com ์ https://example.com → ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์์ง๋ง, ํ๋กํ ์ฝ์ด ๋ค๋ฅด๋ฏ๋ก ๋์ผ ์ถ์ฒ๊ฐ ์๋๋ค.
- http://example.com ์ http://example.com:80 → ์ผํ๋ณด๋ฉด ๋ค๋ฅธ ์ถ์ฒ๊ฐ์ง๋ง, ์ ์์ ๊ฒฝ์ฐ http ์ ๊ธฐ๋ณธ ํฌํธ์ธ 80์ด ์๋ต๋ ํํ์ด๋ฏ๋ก ์ด๋ ๊ฐ์ ์ถ์ฒ.
๋์ผ ์ถ์ฒ๋ผ๋ฆฌ ์์ฒญ์ ์ฃผ๊ณ ๋ฐ์์ผ์ง๋ง SOP๋ฅผ ์งํค๋ ๊ฒ์ด๋ค.
์์ ์๋ ์ถ์ฒ๊ฐ ๋ค๋ฅธ ๊ณณ์ผ๋ก ์์ฒญํ๋ ๊ฒ ์์ฒด๋ฅผ ์ ์์ ํ์๋ก ๊ฐ์ฃผํ๋ค(CSRF, XSS ๋ฑ).
์๋ํ๋ฉด ์์ ์ ์น์ ํ๋ก ํธ์๋ ๋ ์ด์ด์ ๋ฐฑ์๋ ๋ ์ด์ด๋ฅผ ๋ณ๋๋ก ๊ตฌ์ฑํ์ง ์๊ณ ์๋ฒ๊ฐ ์ง์ ์์ฒญ ์ฒ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ HTML ๋ฌธ์๋ก ๋ง๋ค์ด ํด๋ผ์ด์ธํธ์ ์๋ตํ๋ ํ์์ด์๊ธฐ ๋๋ฌธ.
<html>
<head>
<title> PHP example </title>
</head>
<body>
<?php
$i = 1;
while($i<=10)
{
echo $i."๋ฒ์งธ<br />";
$i++;
}
?>
</body>
</html>
๐ ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (Cross-Origin Resource Sharing, CORS)
์๋น์ค์ค์ธ ์ดํ๋ฆฌ์ผ์ด์ ์ ํ๋ก ํธ๋จ์์ ์ 3์๊ฐ ์ ๊ณตํ๋ API๋ฅผ ์ง์ ํธ์ถํด์ผํ๋ ๋ฑ(๊ฒฐ์ API, ์ง๋ API, SNS API, ๋ ์จ API, ๋ฒ์ญ API, ๊ฒ์ ์์ง, ๋ฐ์ดํฐ ์๊ฐํ API, ๋จธ์ ๋ฌ๋ ๋ฐ AI API, ์ธ์ฆ ๋ฐ ์ฌ์ฉ์ ๊ด๋ฆฌ API ๋ฑ..) ์ ์ ์น ์๋น์ค์์ ์๊ตฌ๋๋ ๊ธฐ๋ฅ๋ค์ด ๋์ด๋ฌ๋ค. ํ์ง๋ง SOP๋ผ๋ ๋ธ๋ผ์ฐ์ ์ ์ฑ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ ์ ์์ ์ธ ํ์๋ก ๊ฐ์ฃผ๋์๋ค. ๋ฐ๋ผ์ ํธ์ถํ๊ณ ์ถ์ API๋ฅผ ์ฐ๋ฆฌ์ ๋ฐฑ์๋ ์๋ฒ๋ฅผ ํ๋ฒ ๊ฑฐ์ณ์ ํธ์ถํ๊ฑฐ๋, JSONP ๋ผ๋ ๊ธฐ์ ๋ ๋ฑ์ฅํ์ง๋ง ๊ทผ๋ณธ์ ์ธ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค.
์ด๋ฐ ๋ฐฐ๊ฒฝ์ผ๋ก CORS๊ฐ ๋ฑ์ฅํ๊ฒ ๋์๋ค. ๋ฆฌ์์ค ํธ์ถ์ด ํ์ฉ๋ ์ถ์ฒ๋ฅผ ์๋ฒ๊ฐ ๋ช ์ํด๋์ผ๋ฉด, ์ถ์ฒ๊ฐ ๋ค๋ฅด๋๋ผ๋ ์์ฒญ๊ณผ ์๋ต์ ์ฃผ๊ณ ๋ฐ์ ์ ์๋๋ก ๋ง๋ค์ด๋์ ์ ์ฑ ์ด ๋ฐ๋ก CORS์ด๋ค.
๐ CORS ์ ๊ทผ ์ ์ด ์๋๋ฆฌ์ค
๐ 1. ๋จ์ ์์ฒญ (Simple Requests)
๋ธ๋ผ์ฐ์ ๋ ๋ค๋ฅธ ์ถ์ฒ๋ก์ ์์ฒญ์ ๋ณด๋ผ ๋ ์๋์ผ๋ก HTTP ํค๋์ Origin ์ ์ถ๊ฐํ์ฌ ๋ณด๋ธ๋ค.
Origin: https://foo.example
์ด ์๋ต์ ๋ฐ์ ์๋ฒ๋ ์๋ต ํค๋์ Access-Control-Allow-Origin ์ ์ค์ด ๋ณด๋ธ๋ค. ์ด ํค๋์๋ ํ๊ฐ๋ ์ถ์ฒ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋ค. ์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํด์ ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ ์๋ ์๋ค.
Access-Control-Allow-Origin: *
๋ธ๋ผ์ฐ์ ๋ ์์ฒญ์ Origin ํค๋์ ๋ด๊ธด ์ถ์ฒ ์ ๋ณด๊ฐ ์๋ต์ Access-Control-Allow-Origin ํค๋์ ๋ด๊ฒจ์์ผ๋ฉด ํด๋น ์์ฒญ์ ์์ ํ๋ค๊ณ ๊ฐ์ฃผํ๊ณ ์๋ต์ ๊ฐ์ ธ์จ๋ค. ๋ง์ฝ ๊ทธ๋ ์ง ์๋ค๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ํด๋น ์๋ต์ ์์๋ก ํ๊ธฐํ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์๋ต์ ๋ด์ฉ์ ์ ๋ฌํ์ง ์๋๋ค.
โ ๋จ์ ์์ฒญ์ ์กฐ๊ฑด
ํ์ง๋ง ์์ฒญ์ด ๋จ์ ์์ฒญ์ผ๋ก ์ทจ๊ธ๋๊ธฐ ์ํด์๋ ์๋์ ์กฐ๊ฑด์ ๋ง์กฑํด์ผํ๋ค.
- GET, POST, HEAD ๋ฉ์๋๋ง ํ์ฉ๋๋ค.
- Accept, Accept-Language, Content-Language, Content-Type ํค๋๋ง ํ์ฉ๋๋ค.
- Content-Type ๋ application/x-www-form-urlencoded, multipart/form-data, text/plain ์ด ์ธ๊ฐ์ง ๊ฐ๋ง ํ์ฉ๋๋ค.
- ์์ฒญ์ ์ฌ์ฉ๋ XMLHttpRequestUpload ๊ฐ์ฒด์๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๋ฑ๋ก๋์ด ์์ง ์๋ค. ์ด๋ค์ XMLHttpRequest.upload ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ทผํ๋ค.
- ์์ฒญ์ ReadableStream ๊ฐ์ฒด๊ฐ ์ฌ์ฉ๋์ง ์๋๋ค.
๋จ์ ์์ฒญ์ ํํ์ง ์๋ค.
ํ์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก Content-Type ์ด text/xml์ด๋ application/json ์ปจํ ์ธ ํ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๊ต์ฅํ ๋ง์ผ๋ฉฐ, ์ฌ์ฉ์ ์ธ์ฆ์ ์ํด์ Cookie ํน์ Autorization ์ ๊ฐ์ ์ถ๊ฐ ํค๋๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋จ์ ์์ฒญ์ ์กฐ๊ฑด์ ๋ง์ถ๊ธฐ๋ ์ฝ์ง ์๋ค.
๋ํ ์ ์ด์ ์ ์กฐ๊ฑด์ ๋ช
์๋ ํค๋๋ค์ ์ง์ง ๊ธฐ๋ณธ์ ์ธ ํค๋๋ค์ด๊ธฐ ๋๋ฌธ์, ๋ณต์กํ ์์ฉ ์น ์ดํ๋ฆฌ์ผ์ด์
์์ ์ด ํค๋๋ค ์ธ์ ์ถ๊ฐ์ ์ธ ํค๋๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๋ฉฐ ๋น์ฅ ์ฌ์ฉ์ ์ธ์ฆ์ ์ฌ์ฉ๋๋ Authorization ํค๋์กฐ์ฐจ ์์ ์กฐ๊ฑด์๋ ํฌํจ๋์ง ์๋๋ค.
(= Authorization ํค๋๋ฅผ ์ฌ์ฉํ๋ฉด Simple Request์ ํด๋น๋์ง ์์!)
(= ์ด์ธ์ ๋ค๋ฅธ ์ปค์คํ
ํค๋, ๊ถํ๊ณผ ๊ด๋ จ๋ ํค๋๊ฐ ์์ผ๋ฉด Simeple Request์ ํด๋น๋์ง ์์! )
์ถ๊ฐ์ ์ผ๋ก HTTP ๋ฉ์๋๋ค ์ค GET ์ด ์ธ์ ๋ฉ์๋๋, POST ๋ฉ์๋์์ ํน์ MIME Type์ ์๋ฒ ๋ฐ์ดํฐ์ ์ฌ์ด๋ ์ดํํธ๋ฅผ ๋ฐ์์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ SimpleRequest๊ฐ ์๋ Preflight Request ๋ฐฉ์์ผ๋ก ์์ฒญํ ์ ์๋๋ก ๊ท์ ํ๋ค.
์ฌ์ค์ ์ด ์กฐ๊ฑด๋ค์ ๋ชจ๋ ๋ง์กฑ์ํค๋ ์ํฉ์ ๋ง๋๊ธฐ ์ฝ์ง ์์ Simple Request ๊ฒฝ์ฐ๋ ํํ ๋ณด๊ธฐ ์ด๋ ต๋ค.
๐ 2. ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ (Preflight Requests)
์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ์ฌ์ ์์ฒญ์ ๋ณด๋ด์ ํด๋น ๋ฆฌ์์ค์ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ง ๋จผ์ ํ์ธํ๋ ๋ฐฉ์์ Preflight ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค. Preflight๋ OPTIONS ๋ฉ์๋๋ฅผ ํตํด ์์ฒญ๋๋ค.
Preflight ์์ฒญ์ ๋จ์ ์์ฒญ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ฒญ์ Origin ํค๋๋ฅผ ์ถ๊ฐํด์ผํ๋ค. Preflight ์์ฒญ์ ์ฌ๊ธฐ์ ๋ํ์ฌ ์ค์ ์์ฒญ์ ๋ฉ์๋๋ฅผ Access-Control-Request-Method ํค๋์, ์ค์ ์์ฒญ์ ์ถ๊ฐ ํค๋ ๋ชฉ๋ก์ Access-Control-Request-Headers ํค๋์ ๋ด์ ๋ณด๋ด์ผํ๋ค.
์ค์ ์์ฒญ ์ด์ ์ '์ด๋ฐ ๋ฉ์๋์ ํค๋๋ก ์์ฒญ์ ๋ณด๋ผ ์์ ์ธ๋ฐ, ๋ํฌ ์๋ฒ CORS ์ ์ฑ ์์ ํ์ฉํ๋ ์์ฒญ์ด๋?' ๋ผ๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ์๊ฒ ๋ฏธ๋ฆฌ ๋ฌผ์ด๋ณด๋ ์ ์ฐจ๋ผ๊ณ ๋ณด๋ฉด ์ฝ๋ค.
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
์๋ต ์ญ์ ๋จ์ ์์ฒญ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก Access-Control-Allow-Origin ํค๋๊ฐ ์ ์ก๋์ด์ผ ํ๋ค. ์ฌ๊ธฐ์ ๋ํด ์๋ฒ ์ธก์์ ํ์ฉํ๋ ๋ฉ์๋ ๋ชฉ๋ก์ด ๋ด๊ธด Access-Control-Allow-Methods ํค๋์ ํ๊ฐ ํค๋ ๋ชฉ๋ก์ด ๋ด๊ธด Access-Control-Allow-Headers ํค๋, ๋ง์ง๋ง์ผ๋ก Preflight์ ์บ์ ๊ธฐ๊ฐ์ธ Access-Control-Max-Age ์ ๋ณด๋ด์ค์ผ ํ๋ค.
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Preflight ์์ฒญ ๋๋ฌธ์ ์ค์ ์์ฒญ์ ํ๋ฒ์ด์ง๋ง ๋๋ฒ์ ์์ฒญ์ ๋ณด๋ด์ผํ๋ ์ผ์ด ๋ฐ์ํ๋ค. Preflight ์บ์ ๊ธฐ๊ฐ์ ๋ณด๋ด๋ ์ด์ ๋ Preflight๋ก ๋ฐ์ํ๋ ์ด๋ฐ ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ธฐ ์ํจ์ด๋ค.
โ Preflight ์์ฒญ์ด ํ์ํ ์ด์ ๋ ๋ฌด์์ผ๊น?
์์์ ์ด์ผ๊ธฐํ ๊ฒ ์ฒ๋ผ CORS๋ ์๋ฒ๊ฐ ์๋ ๋ธ๋ผ์ฐ์ ๊ตฌํ ์คํ์ ํฌํจ๋ ์ ์ฑ ์ด๋ค. ๋ฐ๋ผ์ ์๋ฒ๋ CORS ์๋ฐ ์ฌ๋ถ์ ์๊ด์์ด ์ผ๋จ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์๋ต์ ๋ณด๋ธ๋ค. ๊ทธ ์๋ต์ ๋ฐ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ต ํค๋๋ฅผ ํ์ธํ๊ณ ์๋ต์ ํ๊ธฐ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๊ฒ ๋๋ค.
GET๊ณผ HEAD์ ๊ฐ์ ์์ฒญ์ ๋จ์ ์กฐํ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ์๊ด์์ง๋ง, POST, PUT, DELETE ์ ๊ฐ์ ๋ฉ์๋๋ ์๋ฒ์ ๋ถ์์ฉ (Side Effect) ์ ์ผ๊ธฐํ ์ ์๋ค. ์ด๋ ์๋ต์ด ์ ํจํ์ง ์์ ํ๊ธฐํ ๋ธ๋ผ์ฐ์ ์ ์์ฌ์ ์๊ด์์ด ๋ฐ์ํ๋ค.
Preflight๋ ์ค์ ์์ฒญ์ด CORS๋ฅผ ์๋ฐํ์ง ์์๋์ง๋ฅผ ๋ฏธ๋ฆฌ ํ์ธํ๊ณ , ๋ถ์์ฉ์ผ๋ก๋ถํฐ ์๋ฒ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด ์ ์กํ๋ค. ํ์ง๋ง POST์ ๊ฐ์ ๊ฒฝ์ฐ ์กฐ๊ฑด๋ง ๋ง์กฑํ๋ฉด Preflight ์์ฒญ ๋์ ๋จ์ ์์ฒญ์ผ๋ก ์ ์ก๋ ์ ์์ผ๋ฏ๋ก ๋ฐฑ์๋์์๋ ์ด์ ๋ํ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค.
Postman์ด CORS๋ฅผ ๋ฐ์์ํค์ง ์๋ ์ด์ .
์ฐธ๊ณ ๋ก Preflight ์์ฒญ์ ๋ธ๋ผ์ฐ์ ์์ ์๋์ผ๋ก ์ ์ก๋๋ฏ๋ก ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ๋ณด๋ผ ํ์๋ ์๋ค.
๊ฐ๋ฐ์ ํ๋ฉด์ Postman ์ ์ฌ์ฉํ๋ฉด ์ ์์ ์ผ๋ก ์์ฒญ์ด ๋๋๋ฐ, ์น๋ธ๋ผ์ฐ์ ์์ ํธ์ถ ํ๊ธฐ๋ง ํ๋ฉด CORS๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ๊ฒช์ด๋ดค์ ๊ฒ์ด๋ค. ๋ธ๋ผ์ฐ์ ์ ๋ค๋ฅด๊ฒ Postman ๊ณผ ๊ฐ์ API ํ ์คํ ๋๊ตฌ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก Preflight ๋ฅผ ๋ณด๋ด์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
CORS ์ ์ฑ ์๋ฐ ํ์ธ → Access-Control-Allow-Origin ๊ฐ์ด ์กด์ฌ ์ ๋ฌด
๐ฌ ์ฃผ์ํ ์
์๋น ์์ฒญ์ ๋ํ ์๋ต์์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ณ ์ ์์ ์ผ๋ก 200์ด ๋จ์ด์ก๋๋ฐ, ์ฝ์ ์ฐฝ์๋ ๋นจ๊ฐ๊ฒ ์๋ฌ๊ฐ ํ์๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ด๋ CORS ์ ์ฑ ์๋ฐ์ผ๋ก ์ธํ ์๋ฌ๋ ์๋น ์์ฒญ์ ์ฑ๊ณต ์ฌ๋ถ์ ๋ณ ์๊ด์ด ์๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ CORS ์ ์ฑ ์๋ฐ ์ฌ๋ถ๋ฅผ ํ๋จํ๋ ์์ ์ ์๋น ์์ฒญ์ ๋ํ ์๋ต์ ๋ฐ์ ์ดํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌผ๋ก ์๋น ์์ฒญ ์์ฒด๊ฐ ์คํจํด๋ ๋๊ฐ์ด CORS ์ ์ฑ ์๋ฐ์ผ๋ก ์ฒ๋ฆฌ๋ ์๋ ์์ง๋ง, ์ค์ํ ๊ฒ์ ์๋น ์์ฒญ์ ์ฑ๊ณต/์คํจ ์ฌ๋ถ๊ฐ ์๋๋ผ “์๋ต ํค๋์ ์ ํจํ Access-Control-Allow-Origin ๊ฐ์ด ์กด์ฌํ๋๊ฐ”์ด๋ค. ๋ง์ฝ ์๋น ์์ฒญ์ด ์คํจํด์ 200์ด ์๋ ์ํ ์ฝ๋๊ฐ ๋ด๋ ค์ค๋๋ผ๋ ํค๋์ ์ ๊ฐ์ด ์ ๋๋ก ๋ค์ด๊ฐ์๋ค๋ฉด CORS ์ ์ฑ ์๋ฐ์ด ์๋๋ผ๋ ์๋ฏธ์ด๋ค.
→ ์๋ต ์ํ๋ 200์ด์ง๋ง, Access-Control-Allow-Origin์์ ์ฐจ์ด๊ฐ ์๋ ๊ฒ์ ํ์ธ ๊ฐ๋ฅ.
→ 'Access-Control-Allow-Origin: *' ์ด ํค๋๊ฐ ์๋ฏธํ๋ ๊ฒ์ ์ด๋ ํ Origin ์ด๋ ํ์ฉํ๋ค๋ ๋ป์ด๋ฉฐ, ํน์ Origin๋ง ํ์ฉํ๊ณ ์ถ๋ค๋ฉด, ์๋ฒ์์ ์๋ตํค๋์ "Access-Control-Allow-Origin: https://foo.example" ๋ก ๊ฐ์ ์ค์ ํด ์ฃผ๋ฉด ๋๋ค.
๐ 3. ์ธ์ฆ์ ๋ณด๋ฅผ ํฌํจํ ์์ฒญ (Credentialed Requests)
3๋ฒ์งธ ์๋๋ฆฌ์ค๋ ํค๋์ ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ์ ๋ณด(์ฟ ํค, ํ ํฐ ๋ฑ)๋ฅผ ๋ด์์ ๋ณด๋ด๋ Credential Request (์ธ์ฆ๋ ์์ฒญ)์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
CORS์ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์์ด๋ผ๊ธฐ ๋ณด๋ค๋ ๋ค๋ฅธ ์ถ์ฒ ๊ฐ ํต์ ์์ ์ข ๋ ๋ณด์์ ๊ฐํํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์๋ฅผ ๋ค์ด, ์๋ฐ์คํฌ๋ฆฝํธ์ fetch API๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ Axios, Ajax ๋ฑ์ ์ฌ์ฉํ ๋ ์๋ฒ๋ก ์ฟ ํค๋ฅผ ํจ๊ป ์ ์กํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, ์์ฒญ์ ์ฟ ํค๊ฐ ๋ด๊ธฐ๊ฒ ๋๋ฉด Credentialed Request ํ์ฉ์ด ๋์ด ์์ด์ผ ํ๋ค.
์ฆ, ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ์ ๋ณด๋ฅผ ๋ด์ ์ ์๊ฒ ํด์ฃผ๋ ์ต์ 'credentials'๋ฅผ ์ค์ผํ๋๋ฐ, ์ด ๋ ์๋ฒ ์ชฝ์์ ์๋ต ํค๋์ Access-Control-Allow-Credentials: true๋ฅผ ๋ณด๋ด์ฃผ์ง ์๋๋ค๋ฉด ๋ธ๋ผ์ฐ์ ์์ ์๋ต์ ๋ฐ๋ ๊ฒ์ ๊ฑฐ๋ถํ๊ฒ ๋๋ค.
์ด ์ต์ ์๋ ์ด 3๊ฐ์ง์ ๊ฐ์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๊ฐ ๊ฐ๋ค์ด ๊ฐ์ง๋ ์๋ฏธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- same-origin : ๊ฐ์ ์ถ์ฒ ๊ฐ ์์ฒญ์๋ง ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ ์ ์๋ค.
- include : ๋ชจ๋ ์์ฒญ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ ์ ์๋ค.
- omit : ๋ชจ๋ ์์ฒญ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ง ์๋๋ค.
fetch("http://example.com/", {
method: "PUT",
credentials: "include",
})
์ฐธ๊ณ ๋ก XMLHttpRequest ํน์ Axios ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ withCredentials ์ต์ ์ true ๋ก ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
๋ง์ฝ same-origin์ด๋ include์ ๊ฐ์ ์ต์ ์ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค ์์ฒญ์ ์ธ์ฆ ์ ๋ณด๊ฐ ํฌํจ๋๋ค๋ฉด, ์ด์ ๋ธ๋ผ์ฐ์ ๋ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ๋ ๋จ์ํ Access-Control-Allow-Origin๋ง ํ์ธํ๋ ๊ฒ์ด ์๋๋ผ ์ข ๋ ๋นก๋นกํ ๊ฒ์ฌ ์กฐ๊ฑด์ ์ถ๊ฐํ๊ฒ ๋๋ค.
์์ฒญ์ ์ธ์ฆ ์ ๋ณด๊ฐ ๋ด๊ฒจ์๋ ์ํ์์ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๊ฒ ๋๋ฉด ๋ธ๋ผ์ฐ์ ๋ CORS ์ ์ฑ ์๋ฐ ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํ๋ ๋ฃฐ์ ๋ค์ ๋ ๊ฐ์ง๋ฅผ ์ถ๊ฐํ๊ฒ ๋๋ค.
- Access-Control-Allow-Origin์๋ * (์์ผ๋์นด๋)๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ช
์์ ์ธ URL์ด์ด์ผํ๋ค.
(https://foo.com๊ณผ ๊ฐ์ด ๊ตฌ์ฒด์ ์ธ origin์ ์ง์ ํด์ฃผ์ด์ผ ํ๋ค.) - ์๋ต ํค๋์๋ ๋ฐ๋์ Access-Control-Allow-Credentials: true๊ฐ ์กด์ฌํด์ผํ๋ค.
๐ ์ถ์ฒ
https://www.baeldung.com/cs/cors-preflight-requests
'infra & network' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
HTTPS๋ (SSL / TLS) (0) | 2024.08.11 |
---|---|
[Network] ๋ง์ฝ DNS๊ฐ ์์ฒญํ ๋๋ฉ์ธ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๋ค๋ฉด? (0) | 2024.06.09 |
[Network] ์น ๋ธ๋ผ์ฐ์ ์ URL์ ์ ๋ ฅํ๋ค๋ฉด ์ผ์ด๋๋ ์ผ (2) | 2024.05.19 |
๋๊ธ