CORS๋ผ๊ณ ๋ถ๋ฆฌ๋ ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ ๋ ํ๋์ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
์น์ฌ์ดํธ๋ ๋ณด์์ ์ํด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ์ถ์ฒ์ธ ๊ณณ๊ณผ๋ ํต์ ์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ ์ง๋ง CORS ์์ ๊ท์น๋ค์ ํต๊ณผํ๊ฒ ๋๋ฉด ๋ค๋ฅธ ์ถ์ฒ์ธ ๊ณณ๊ณผ ํต์ ์ ํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ ํฌ๊ฐ ์์ฃผ ๋ณด๋ CORS ์๋ฌ๋ ์๋ฒ๊ฐ ์ด ๊ท์น์ ์งํค์ง ๋ชปํด ๋ธ๋ผ์ฐ์ ๊ฐ ๊ท์น ์ข ์ง์ผ์ค๋?
ํ๊ณ ์๋ ค์ฃผ๋
๊ฒ์
๋๋ค.
CORS๋ฅผ ํ์ฉํ๋ ๊ท์น์ Access-Control-Allow-Origin
๋ฅผ ์๋ฒ์ ๋์ผํ URL๋ก ๋ง์ถ๋ ๊ฒ ๋ฑ๋ฑ ๋ค์ํ๊ฒ ์์ต๋๋ค.
(์์ธํ ๋ด์ฉ์ ๐ธ CORS ๋์๊ณผ์ ์ ๋ฆฌ ์ flowchart๋ก ์ค๋ช ๋์ด ์์ต๋๋ค.)
์๋ง ์ด ๊ธ์ ์ฝ์ผ์๋ ๋ถ๋ค์ ๋๋ถ๋ถ CORS๊ฐ ๋ณด์์ ์ํด ์กด์ฌํ๋ค๋ ๊ฒ์ ์๊ณ ๊ณ์ค ๊ฒ์ ๋๋ค. ํ์ง๋ง CORS๋ ์ค๋ ๊ธฐ๊ฐ ๋ฐ์ ๋์ด ์จ ๊ฒฐ๊ณผ์ ๋๋ค.
์ฒ์๋ถํฐ CORS ๋ฉ์ปค๋์ฆ์ ๋ธ๋ผ์ฐ์ ์ ์ ์ฉ์ํจ ๊ฒ์ด ์๋๋๋ค. ์ด ๋ฌธ์ฅ์ ๋ฃ๊ณ ๊ถ๊ธ์ฆ์ ๋๋ผ์ จ๋ค๋ฉด ์ด ๊ธ์ด ๋์๋๊ธธ ๋ฐ๋๋๋ค.
๊ณผ๊ฑฐ์ ์ธํฐ๋ท
1980๋ ๋์ ์ธํฐ๋ท์๋ ์ ์ ์๋ ํ๋ถํ ์ฝํ ์ธ ๊ฐ ์์๊ณ ์ผ๋ฐ ํ ์คํธ์ ์ผ๋ฐ ํ์ผ๋ง ์์์ต๋๋ค.
์๊ฐ์ด ์ง๋ 1989๋ ์ Tim Berners-Lee๊ฐ ๋จ์ํ ํ ์คํธ๊ฐ ์๋ ํ๋ถํ ์ปจํ ์ธ ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ผ๋ก World Wide Web์ ๋ฐ๋ช ํ์์ต๋๋ค.
์ด ์์ด๋์ด๋ Netscape Navigator๋ Mosaic์ด๋ผ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ํญ๋ฐ์ ์ธ ์ธ๊ธฐ๋ฅผ ๋๊ธฐ ์์ํฉ๋๋ค.
๋ช ๋
ํ, 1994๋
์๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ป๊ธฐ ์ํ์ฌ ์ฟ ํค๊ฐ ๋ฐ๋ช
๋์์ต๋๋ค.
์ฟ ํค๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ์ด์ ์ ์น์ฌ์ดํธ๋ฅผ ๋ฐฉ๋ฌธํ ์ ์ด ์๋์ง, ์ ์ ์๊ฑฐ๋ ์น์ฌ์ดํธ๋ผ๋ฉด ์ด์ ์ ์ผํํ ํญ๋ชฉ์ ๋ฌด์์ธ์ง ์ ์ฅํ ์ ์์์ต๋๋ค.
์ฟ ํค๋ฅผ ์ถ๊ฐํ Netscape๋ ์ด๋ฌํด ์น ๋ธ๋ผ์ฐ์ ์ 2๊ฐ์ง ์๋ก์ด ๊ธฐ๋ฅ์ ๋์ ํ์ฌ ๋ ๋ฉ์ง ์น์ฌ์ดํธ๋ฅผ ๋ง๋ค์ด๊ฐ๊ธฐ ์์ํ์ต๋๋ค.
๋ฐ๋ก JavaScript์ DOM์ด๋ผ๊ณ ํ๋ HTML ์์์ ์ ๊ทผํ ์ ์ ๋ API์ ๋๋ค.
DOM ๋๋ถ์ JavaScript๋ฅผ ์ด์ฉํ์ฌ ํ์ด์ง URL, ์ฟ ํค, ์ฌ์ฉ์๊ฐ ๋ฐ์์ํค๋ ์ด๋ฒคํธ๊น์ง HTML ๋ฌธ์์ ๋ชจ๋ ์์์ ์ ๊ทผํ ์ ์๊ฒ๋ ๊ฒ์ ๋๋ค!
HTML์ด ํ๋ถํด์ง๋ฉด์ ๋ค๋ฅธ ๋ฌธ์๋ ๋ฏธ๋์ด ํญ๋ชฉ๊ณผ ๊ฐ์ ์ถ๊ฐ ๋ฆฌ์์ค๊ฐ ์๊ฒจ๋ฌ๊ณ , ์ด๋ฌํ ๋ฆฌ์์ค์๋ ์์ฒด ์ฟ ํค, DOM, JavaScript ๋ค์์คํ์ด์ค ๋ฐ ๊ธฐํ ํ๋ถํ ์์๊ฐ ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ์ ๋ฒ์ ๋ด์์ ์ด๋ฌํ ์ํฐํฐ์ ์์ ํ๊ฒ ์ํธ ์์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด ํ์ํ์ต๋๋ค. ๊ทธ๋ ๊ฒ ์๊ฒจ๋ ๊ฒ์ด SOP(Same-Origin Policy, ์ดํ ๋์ผ ์ถ์ฒ ์ ์ฑ ) ์ ๋๋ค.
๋์ผ ์ถ์ฒโฆ.์?
๊ฐ๋จํฉ๋๋ค!
์์ฒญ์ ๋ณด๋ผ ๋ ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ, URL์ด ์ผ์นํ๋ฉด ๋์ผํ ์ถ์ฒ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. ์์๋ก ํ์ธํด๋ด ์๋ค!
http://example.com/script.js ์์ ์ถ๋ฐํ๋ค๋ฉดโฆ
- โ ย http://example.com/api/
- โย http://example.org/api/
- โย http://api.example.org/
- โย http://example.com:8000/api/
- โย https://example.com/api/
๋ง์ฝ ๋์ผ ์ถ์ฒ ์ ์ฑ ์ด ์์๋ค๋ฉด?!
๋ณด์์ ์ํด ์ถ๊ฐํ ๋์ผ ์ถ์ฒ ์ ์ฑ ์ด ๋ง์ฝ ์์๋ค๋ฉด ์ ํฌ์ ์ธํฐ๋ท ์ธ์์ ์ด๋ป๊ฒ ๋์์๊น์?
์ฌ๋ฌ๋ถ์ด ์ด๋ป๊ฒ๋ ์์์ www.your-bank.bad-site.com ์ ๋ฐฉ๋ฌธํ๊ฒ ๋์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
๊ทธ ๋์ ์ฌ์ดํธ์๋ www.your-bank.com ์ ๋ก๋ํ๋ iframe์ด ์์ผ๋ฉฐ ํด๋น ์ฌ์ดํธ์์ ํฉ๋ฒ์ ์ผ๋ก ๋ก๊ทธ์ธ์ ์งํํฉ๋๋ค.
๋ก๊ทธ์ธ ํ ์ ์ฑ ์ฌ์ดํธ์์ ๊ฐ๋จํ JavaScript ํธ์ถ์ ์ด์ฉํ์ฌ iframe์ ๋ก๋๋ ๊ณ์ข ์์ก ๋ฐ์ดํฐ DOM ์์์ ์ฝ๊ฒ ์ ๊ทผํ ์ ์๊ฒ ๋ฉ๋๋ค.
frames.bank_frame.document.getElementById('balance').value;
์ฌ๋ฌ๋ถ์ ์์ง์๋ ์๊ด์์ด ์ฌ์ดํธ ๊ฐ์ ์์ฒญ์ด ํ๋ฝ๋์ด ๊ณ์ข์ ์๋ ๋์ ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ธ์ถํ ์๋ ์๊ฒ ๋๋ ๊ฒ์ ๋๋คโฆ!
์ด ์์๋ฅผ ์ ๋ฌธ ์ฉ์ด๋ก CSRF(Cross-Site Request Forgery, ํฌ๋ก์ค ์ฌ์ดํธ ์์ฒญ ์์กฐ)๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ XSS์๋ ๋ค๋ฅด๊ฒ ์ฌ์ฉ์์ ์ธ์ฆ๋ ์ธ์ ์ ์ ์ฉํ์ฌ ๊ณต๊ฒฉํ๋ ๋ฐฉ์์ ๋๋ค.
๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์ด CSRF ๊ณต๊ฒฉ์ ๋ง๊ธฐ ์ํด ๋ฐ๋ช ๋์์ต๋๋ค.
๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์ด๋ป๊ฒ ๋์ํ๋์?
์ด์ ๊ธ์์ ๋ ๋๋ฌ ํ๋ก์ธ์ค๊ฐ ํ๋ฉด ๊ทธ๋ฆฌ๋ ๊ณผ์ ์ ์งํํ๋ค๊ณ ์ด์ผ๊ธฐํ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ๋ง๋ค ๋ค๋ฅผ ์ ์์ง๋ง Chrome์์๋ ๊ฐ ์ฌ์ดํธ ๋ณ๋ก ํ๋ก์ธ์ค๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ด์ฉํด ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์งํฌ ์ ์๋๋ก ํฉ๋๋ค.
์ฌ์ดํธ ๊ฒฉ๋ฆฌ(site isolation)๋ 2018๋ ๋์ ์ ์ฉ๋ ๊ธฐ๋ฅ์ด๋ฉฐ ๋น๊ต์ ์ต์ ๊ธฐ๋ฅ์ ๋๋ค.
๊ฐ ์ฌ์ดํธ๋ฅผ ์์ฒด ํ๋ก์ธ์ค๋ก ๊ฒฉ๋ฆฌํ์ฌ ์ ๋ขฐํ ์ ์๋ ์น์ฌ์ดํธ๊ฐ ๋ค๋ฅธ ์น์ฌ์ดํธ์ ๊ณ์ ์ ๋ณด์ ์ก์ธ์คํ๊ฑฐ๋ ์ ๋ณด๋ฅผ ํ์น๋ ๊ฒ์ ๋ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
๊ทผ๋ฐ CORS๋์?
๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์๋ ์์ด๋ ์น์ ์ด์ฐฝ๊ธฐ ๊ตฌ์กฐ์ ๋๋ค.
์ค๋๋ ์ฐ๋ฆฌ๊ฐ ์๊ณ ์๋ ์ธํฐ๋ท์ ์ฝํ ์ธ , ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ, ๋จ์ผ ํ์ด์ง ๋์์ธ, ์ข์์ ๋ฐ ๊ณต์ ๋ฑ์ ํ๋ถํ ์ํ๊ณ๋ก ํญ๋ฐ์ ์ผ๋ก ์ฑ์ฅํ์ต๋๋ค.
์ด ๋ค์์ฑ๊ณผ ๋ณํ๋ฅผ ์ง์ํ๊ธฐ ์ํด ๋์ผ ์ถ์ฒ ์ ์ฑ ๋ ํ์ฅํ๊ณ ์ ์ํด์ผ ํ์ต๋๋ค.
ํ์ง๋ง CORS๊ฐ ๋ฐ๋ก ๋ฑ์ฅํ ๊ฒ์ ์๋๋๋ค.
XmlHTTPRequest
์น์ ๋ ํ๋ถํ๊ฒ ๋ง๋ค๊ธฐ ์ํด HTTP ํต์ ์ ํ ์ ์๋๋ก ํ๋ API์
๋๋ค.
๋งค๋ฒ ์๋ก์ด ํ์ด์ง๋ฅผ ๋ก๋ํ ํ์๊ฐ ์๋๋ก ๋ฆฌ์์ค ๊ฐ์ ๋น๋๊ธฐ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
ํต์ ํ ๋ ๋ฐ์ํ ์ ์๋ ์ ์ฌ์ ์ธ ์ํ์ ๊ฐ์ํ ๋ XmlHTTPRequest๋ ๋์ผ ์ถ์ฒ ์ ์ฑ ๊ท์น์ ์๊ฒฉํ๊ฒ ์ ์ฉํด์ผ ํ๋ ์์ญ์ด๊ธฐ๋ ํฉ๋๋ค.
๊ทธ๋ ๊ธฐ์ XmlHTTPRequest์ ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์๊ตฌ์ฌํญ์ด ์์ ํ ์ ์ฉ๋์์ต๋๋ค.
- ๋ค๋ฅธ ์ถ์ฒ ์ฌ์ดํธ๋ก ํธ์ถํ ์๋ ์์์ง๋ง, ์๋ต์ ์ฝ์ ์ ์์ต๋๋ค.
- ์์ฒญ URL์ด ๊ฐ์ ์ถ์ฒ์ ์๋ค๋ฉด ์๋ต์ ์ฝ์ ์ ์์ต๋๋ค.
- ์ฌ์ฉ์ ์ง์ ํค๋๋ ๊ฐ์ ์ถ์ฒ์ ๋ํ ์์ฒญ์๋ง ์ถ๊ฐํ ์ ์์ต๋๋ค.
JSONP
XmlHTTPRequest๋ฅผ ์ด์ฉํ์ฌ ๋ค๋ฅธ ์ถ์ฒ์ ๋ํ ๋น๋๊ธฐ ํต์ ์ ๋ง๋ค ์ ์์์ง๋ง ์๋ต์ ์ฝ์ ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค๋ฅธ ์ฌ์ดํธ์์ ๋ฐ์ ํ์จ, ์ผ๊ธฐ ์๋ณด, ์จ๋ฒ ๋ชฉ๋ก ๋ฑ์ ๊ธฐํ ์ ๋ณด๋ ์ด๋ป๊ฒ ํ์ํ ์ ์์์๊น์?
๋์ผ ์ถ์ฒ ์ ์ฑ
์ผ๋ก ์ธํด ์ง์ ์ ์ธ HTTP ํต์ ์ ํตํ์ฌ ์ธ๋ถ ์ถ์ฒ์ธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
ํ์ง๋ง HTML์ <script>
์์๋ ์ธ๋ถ ์ถ์ฒ๋ก๋ถํฐ ์กฐํ๋ ๋ด์ฉ์ ์คํํ ์ ์์ต๋๋ค.
์ด ์ฝ๋๋ ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์ด๊ธ๋์ง๋ง,
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://server.example.com/Users/1234', true);
xmlhttp.onload = function () {
console.log('Retrieved Data: ' + xmlhttp.responseText);
};
xmlhttp.send(); // -> ๊ต์ฐจ ์ถ์ฒ ์์ฒญ ์ฐจ๋จ
์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ผ ์ถ์ฒ ์ ์ฑ
๊ณผ๋ ๊ด๊ณ์์ด ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค.
ํ์ง๋ง JS ๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
<script type="application/javascript" src="http://server.example.com/Users/1234"></script>
ํด๋น ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด { ... }
์ฒ๋ผ JSON ๋ฌธ๋ฒ์ด ๋์ฌ ๊ฒ์ด๊ณ , ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์์ ์ค๊ดํธ ๋ฌธ๋ฒ์ block์ผ๋ก ํด์ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
JSONP๋ ์ด๋ฐ ์น ๋ธ๋ผ์ฐ์ ํน์ฑ์ ์ด์ฉํด JSON ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ ์ง์ ํ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ๋ ์ ํจํ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ผ๋ก ๊ฐ์ธ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์กํ์ต๋๋ค.
// ์๋ฒ์์ ๋ณด๋ด๋ ๊ฐ
parseResponse({ Name: 'Foo', Id: 1234, Rank: 7 });
// ํด๋ผ์ด์ธํธ์์ ๋ฐ๋ ๊ฐ
<script
type="application/javascript"
src="http://server.example.com/Users/1234?callback=parseResponse"
></script>;
์ด๊ฒ ๋ํ ๋ณด์ ์ํ์ ์ด๋ํ ์ ์์ต๋๋ค.
JSONP ์์ฒญ์ด ์คํ๋๋ฉด JS๋ ํด๋น ๋ฆฌ์์ค์์ ๋ฐํ๋ ๋ชจ๋ ํญ๋ชฉ์ ์ ๋ขฐํ ์ ์๋ค๊ณ ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
CORS ๋ฑ์ฅ!
JSONP๋ฅผ ์ด์ฉํ๋ฉด ๋์ผ ์ถ์ฒ ์ ์ฑ ์ผ๋ก ์ธํฐ๋ท ์ธ์์ ๋ ์์ ํ๊ฒ ๋ง๋๋ ค๋ ๊ฐ๋ฐ์์ ๋ธ๋ผ์ฐ์ ๊ณต๊ธ์ ์ฒด์ ์ด๋ง์ ๋ถ์ํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ๋ณธ์ง์ ์ธ ์ด์ ๋ JSONP๋ก ๋ง๋ ์ธ๋ถ ์ถ์ฒ์์ ํต์ ์ด ๋จ๋ฐฉํฅ์ด๋ฉฐ ์ฝ๊ธฐ ์ ์ฉ์ด๋ผ๋ ๊ฒ์ ๋๋ค.
๊ณต๊ธ์ ์ฒด๋ ์ด๋ฐ ์ด๋ง์ ๊ณ ๋ คํ์ฌ 2๊ฐ์ง ์๋ฃจ์ ์ ์ ๊ณตํ์ต๋๋ค.
Microsoft๋ ๊ณ ์ ํ ์์ด๋์ด๋ฅผ ๊ฐ์ง๊ณ ์์๊ธฐ์ IE8~9์์ XDomainRequest๊ฐ ์๋ฃจ์ ์ด ๋์๊ณ , Chrome๊ณผ Firefox ๋ฑ์ ๊ธฐํ ๋ธ๋ผ์ฐ์ ์์ CORS(Cross-Origin Resource Sharing)๋ผ๋ ๋์ฒด ๊ธฐ๋ฅ์ ๊ตฌํํ์ต๋๋ค.
CORS
๋๋์ด CORS์ ๋์ฐฉํ์ต๋๋ค.
CORS๋ ์ถ๊ฐย HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ, ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ ์ ๋๋ค.
์ฆ, ๋ธ๋ผ์ฐ์ ์ ๊ตฌํ ์คํ์ ํฌํจ๋๋ ์ ์ฑ ์ด๋ผ๋ ๊ฒ์ ๋๋ค.
์๋ฒ๋ ํ์์ฒ๋ผ ์์ฒญ์ด ์ค๋ฉด ์๋ต์ ํด์ค ๋ฟ์ด๊ณ ,ย ๋ธ๋ผ์ฐ์ ๊ฐ ์์ ์ด ๋ณด๋ธ ์์ฒญ ๋ฐ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ์๋ต์ ๋ฐ์ดํฐ๊ฐ CORS ์ ์ฑ ์ ์งํค๋์ง ๊ฒ์ฌํ์ฌ ์์ ํ ์์ฒญ์ ๋ณด๋ธ ๊ฑด์ง ๊ฒ์ฌ๋ฅผ ์งํํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์๋ต์ ํ๋๋ผ๋, ์์ ํ ์์ฒญ์ด ์๋๋ผ๊ณ ํ๋จ๋๋ฉด ํด๋น ์๋ต์ ๋ฒ๋ฆฝ๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ์ง ์๋ ์๋ฒ ๊ฐ ํต์ ์์๋ย ์ด๋ฌํ ์ ์ฑ ์ด ์ ํ ์ ์ฉ๋์ง ์๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
CORS ์์ฒญ์ ๋จ์ ์์ฒญ๊ณผ ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ+์ค์ ์์ฒญ์ ํ๋ ๋ ๊ฐ์ง ์ํฉ์ด ์์ต๋๋ค.
ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ ์ผ๋ฐ์ ์ผ๋ก ์ ๋ขฐํ ์ ์๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๋น์ ํ ํน์ฑ์ผ๋ก ์ธํด ์๋ฒ์ ๋ํด ์ถ๊ฐ์ ์ธ ๊ฒ์ฆ์ ์งํํ๋ ๊ฒ์ ๋๋ค.
๋จ์ ์์ฒญ์ธ ๊ฒฝ์ฐ
๋ง์ฝ Origin์ ํฌํจํด ์๋์ ๊ฐ์ด ์์ฒญ์ ๋ณด๋๋ค๋ฉด,
GET / HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en,en-US;q=0.5
Origin: http://www.acceptmeplease.com
Connection: keep-alive
์๋ฒ์์ ์ค๋ ์๋ต์ Access-Control-Allow-Origin
๊ฐ์ ํฌํจํ์ฌ ์ฌ ๊ฒ์
๋๋ค.
HTTP/1.1 200 OK
Date: Sun, 24 Apr 2016 12:43:39 GMT
Server: Apache
Access-Control-Allow-Origin: http://www.acceptmeplease.com
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: application/xml
Content-Length: 423
<?xml version="1.0" encoding="UTF-8"?>
์ฌ์ ์์ฒญ์ด ํ์ํ ๊ฒฝ์ฐ (ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ)
CORS ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ๋ธ๋ผ์ฐ์ ๋ OPTIONS ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ํ์ธ ์์ฒญ์ ๋ณด๋
๋๋ค.
์ด๊ฒ์ด ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์
๋๋ค.
OPTIONS ๋ฉ์๋๋ก Access-Control-Request-Method
ย ๋ฐย Access-Control-Request-Headers
๋ผ๋ ๋ ๊ฐ์ ์ถ๊ฐ ํค๋๊ฐ ์ ์๋์ด ์์ต๋๋ค.
์ด๋ ์ถ๊ฐ HTTP ํค๋๊ฐ ์ ์๋ ์ค์ ์์ฒญ์์ ๋ธ๋ผ์ฐ์ ์ ์๋๋ฅผ ์๋ ค์ฃผ๊ธฐ ๋๋ฌธ์ ์ค์ํฉ๋๋ค.
OPTIONS /resources/post-here/ HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Connection: keep-alive
Origin: http://www.acceptmeplase.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-TOKEN-ID
OPTIONSย ์์ฒญ์ ์๋ฝํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์๋ตํฉ๋๋ค.
HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache
Access-Control-Allow-Origin: http://www.acceptmeplease.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-TOKEN-ID
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
์๋ต ์ฝ๋๊ฐ 200์ผ๋ก ๋ฐํ์ ํด์ผ ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ด ํ์ฉ๋ ๊ฒ์ผ๋ก ์ธ์ํฉ๋๋ค.
ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ ํตํด ์๋ ํค๋๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
- Access-Control-Allow-Origin: ์์ฑ๋ origin๊ณผ ์์ฒญํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์์ผ๋์นด๋(*)๋ฅผ ์์ฑํ๋ฉด ๋ชจ๋ ๋๋ฉ์ธ์ ์ ๊ทผํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
- Access-Control-Allow-Methods: ๋ฆฌ์์ค์ ์ ๊ทผํ ๋ ํ์ฉ๋๋ HTTP ๋ฉ์๋๋ฅผ ์๋ฏธํฉ๋๋ค.
- Access-Control-Allow-Headers: ์ค์ ์์ฒญ ์ ์ฌ์ฉํ ์ ์๋ HTTP ํค๋ ๋ชฉ๋ก์ ์๋ฏธํฉ๋๋ค.
- Access-Control-Max-Age: ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ ์ ์ป์ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ ์ ์๋ ๊ธฐ๊ฐ์ ์๋ฏธํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ง๋ค ๋ค๋ฅด์ง๋ง ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์์์ ์ด ๊ฐ์ ์ต๋ 10๋ถ์ ๋๋ค.
์ด์ ์ค์ ์์ฒญ์ด ์งํ๋ฉ๋๋ค.
ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ผ๋ก ์ธํด Content-Type HTTP ํค๋์ X-Token-ID HTTP ํค๋๊ฐ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
POST /resources/post-here/ HTTP/1.1
Host: cors.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Connection: keep-alive
X-Token-ID: aabbccddeeff0011223344556677889900
Content-Type: application/xml; charset=UTF-8
Content-Length: 55
Origin: http://www.acceptmeplease.com
Pragma: no-cache
Cache-Control: no-cache
<?xml version="1.0"?>
...
์ถ๊ฐ๋ก ์ฟ ํค ๊ฐ์ ์ธ์ฆ ๊ฐ์ ํฌํจํ ์์ฒญ์ด๋ผ๋ฉดโฆ
์ฟ ํค ๋ฑ์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ณด๋ด๊ธฐ ์ํด์๋ ํด๋ผ์ด์ธํธ ๋จ์์ ์์ฒญ ์ ๋ณ๋์ ์ค์ ์ด ํ์ํฉ๋๋ค.
Axios๋ฅผ ์ฌ์ฉํ๋ค๋ฉด withCredentials
์ต์
์, fetch API๋ฅผ ์ฌ์ฉํ๋ค๋ฉด credentials
์ต์
์ ์ค์ ํด์ค์ผ ํฉ๋๋ค.
์ด๋ฐ ์ค์ ์ ํ์ง ์๋๋ค๋ฉด ์ฟ ํค๋ Authorization ํค๋์ ์ค์ ํ๋ ํ ํฐ ๊ฐ ๋ฑ์ ์ ๋๋ก ์๋ฒ์๊ฒ ์ ์ก๋์ง ์์ต๋๋ค.
์์ ๊ฐ์ ์ค์ ์ ํตํด ์ธ์ฆ ์ ๋ณด๋ฅผ ์์ฒญ์ ํฌํจ์์ผฐ๋ค๋ฉด, ์ด ์์ฒญ์ ์ด์ ์ธ์ฆ ์ ๋ณด๋ฅผ ํฌํจํ ์์ฒญ์ด ๋ฉ๋๋ค.
์๋ฒ๋ ์ด๋ฌํ ์์ฒญ์ ๋ํด ์ผ๋ฐ์ ์ธ CORS ์์ฒญ๊ณผ๋ ๋ค๋ฅด๊ฒ ๋์ํด์ค์ผ ํฉ๋๋ค.
์๋ต์ย Access-Control-Allow-Origin
ย ํค๋๊ฐ ์์ผ๋์นด๋(*
)๊ฐ ์๋ ๋ถ๋ช
ํ Origin์ผ๋ก ์ค์ ๋์ด์ผ ํ๊ณ ,ย Access-Control-Allow-Credentials
ย ํค๋๋ย true
๋ก ์ค์ ๋์ด์ผ ํฉ๋๋ค.
CORS ๋์๊ณผ์ ์ ๋ฆฌ
์ฐธ๊ณ ์๋ฃ
- https://medium.com/@electra_chong/what-is-cors-what-is-it-used-for-308cafa4df1a
- https://developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy
- https://d2.naver.com/helloworld/2922312
- https://chromium.googlesource.com/chromium/src/+/main/docs/process_model_and_site_isolation.md
- https://www.invicti.com/learn/same-origin-policy-sop/
- https://www.invicti.com/white-papers/whitepaper-same-origin-policy
- https://en.wikipedia.org/wiki/HTTP_cookie
- https://www.digitaltrends.com/computing/history-of-cookies-and-effect-on-privacy/
- https://chromium.googlesource.com/chromium/src/+/main/docs/process_model_and_site_isolation.md
- https://developer.chrome.com/blog/site-isolation/
- http://seclab.stanford.edu/websec/chromium/chromium-security-architecture.pdf
- https://www.youtube.com/watch?v=YvVwrcaxxbQ
- https://web.dev/cross-origin-resource-sharing
- https://nordvpn.com/ko/blog/csrf/
- https://www.chromium.org/Home/chromium-security/site-isolation/#motivation
- https://d2.naver.com/helloworld/2922312
- https://ko.wikipedia.org/wiki/JSONP
- https://evan-moon.github.io/2020/05/21/about-cors/
- https://ko.javascript.info/fetch-crossorigin