CORS
์น ๊ฐ๋ฐ์ ํ๋ค ๋ณด๋ฉด, ๋์ ํ๋ฅ ๋ก ์๋์ ๊ฐ์ ์๋ฌ๋ฅผ ๋ง๋๋ ๊ฒฝํ์ ํ๊ฒ ๋ ์ ์๋ค.
์ด ์๋ฌ๊ฐ ๋ฐ๋ก CORS ์๋ฌ๋ก, CORS ์ ์ฑ
์ ์๋ฐํ์ ๋ ๋ฐ์ํ๋ ์๋ฌ์ด๋ค.
์น์์ ๋ค๋ฅธ ์ถ์ฒ๋ก์ ๋ฆฌ์์ค ์์ฒญ ์ ํ๊ณผ ๊ด๋ จ๋ ์ ์ฑ
์ผ๋ก CORS
, SOP
๋ ๊ฐ์ง๊ฐ ์กด์ฌํ๋ค. ์ด ๋ ๊ฐ์ง ์ ์ฑ
๊ณผ CORS ์๋ฌ์ ๋ํด ์ดํด๋ณด์.
๐ ์ถ์ฒ(Origin)
์ถ์ฒ๋ URL์์ ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ๋ก ์กฐํฉ๋ ๋ถ๋ถ์ ์๋ฏธํ๋ค. ์ ์ค ํ๋๋ผ๋ ๋ค๋ฅด๋ฉด ๋์ผํ ์ถ์ฒ๋ก ๋ณด์ง ์๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ ์ฝ์ ์ฐฝ์
location.origin
์ ์คํํ๋ฉด ์ถ์ฒ๋ฅผ ํ์ธํ ์ ์๋ค.
โถ๏ธ ๋์ผ ์ถ์ฒ, ๊ต์ฐจ ์ถ์ฒ
https://www.example.com:443/dir
,http://www.example.com:443/dir
โณ ํ๋กํ ์ฝ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ต์ฐจ ์ถ์ฒ์ด๋ค.https://www.example.com:443/dir
,https://www.otherexample.com:443/dir
โณ ํธ์คํธ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ต์ฐจ ์ถ์ฒ์ด๋ค.https://www.example.com:443/dir
,https://www.example.com:443/dir2
โณ ๊ฒฝ๋ก๋ง ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋์ผ ์ถ์ฒ์ด๋ค.https://www.example.com:443/dir
,https://www.example.com:443/dir/inner
โณ ๊ฒฝ๋ก๋ง ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋์ผ ์ถ์ฒ์ด๋ค.https://www.example.com:443/dir
,https://www.example.com:80/dir
โณ ํฌํธ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๊ต์ฐจ ์ถ์ฒ์ด๋ค.https://www.example.com:443/dir
,https://www.example.com/dir
โณ ๋์ผ ์ถ์ฒ์ด๋ค. (https
ํ๋กํ ์ฝ์ ๊ธฐ๋ณธ ํฌํธ๋443
)
๐ SOP (Same-Origin Policy)
SOP๋ Same-Origin-Policy์ ์ค์๋ง๋ก, ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ๋ปํ๋ค.
๋ธ๋ผ์ฐ์ ์ ๋ณด์ ๊ด๋ จ ์ ์ฑ ์ SOP(Same-Origin Policy)์ CORS(Cross Origin Resource Sharing)์ด ์๋ค.
- ๋์ผ ์ถ์ฒ ์ ์ฑ
(same-origin policy)์ ์ด๋ค ์ถ์ฒ์์ ๋ถ๋ฌ์จ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค์ ์ํธ์์ฉํ๋ ๊ฒ์ ์ ํํ๋ ๋ณด์ ๋ฐฉ์์ด๋ค.
- SOP๋ ๋ค๋ฅธ ์ถ์ฒ๋ก ์์ฒญ์ ๋ณด๋ผ ์ ์๋๋ก ๊ธ์งํ๋ ๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ์ ์ธ ๋ณด์ ์ ์ฑ ์ด๋ค.
ํ๋ง๋๋ก โ๊ฐ์ ์ถ์ฒ์ ๋ฆฌ์์ค๋ง ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋คโ, โ๋์ผํ ์ถ์ฒ๋ก๋ง ์์ฒญ์ ๋ณด๋ผ ์ ์๋คโ๋ผ๋ ์ ์ฑ ์ด๋ค.
์ด SOP๋ ์์ฃผ ๊ธฐ๋ณธ์ ์ธ ๋ณด์ ์ ์ฑ ์ด์ง๋ง, ์น์์๋ ๋ค๋ฅธ ์ถ์ฒ์ ์๋ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์์ ์ฌ์ฉํ๋ ์ผ์ด ์์ฃผ ํํ๊ธฐ ๋๋ฌธ์ SOP๋ ๋ณ๋์ ์์ธ์ฌํญ์ ๋๊ณ ๋ช ๊ฐ์ง ์์ธ ์ํฉ์ ๋ํด ๋ค๋ฅธ ์ถ์ฒ๋ก๋ ์์ฒญ์ ๋ณด๋ผ ์ ์๋๋กํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ค ํ๋๊ฐ CORS ์์ฒญ์ ์งํจ ๋ฆฌ์์ค ์์ฒญ์ด๋ค.
Generally, reading information from another origin is forbidden. However, an origin is permitted to use some kinds of resources retrieved from other origins. For example, an origin is permitted to execute script, render images, and apply style sheets from any origin. Likewise, an origin can display content from another origin, such as an HTML document in an HTML frame. Network resources can also opt into letting other origins read their information, for example, using Cross-Origin Resource Sharing.
์ฆ, ์ด ์๋ฌ๋ SOP ๋๋ฌธ์ ์ผ์ด๋๊ฒ ๋ ์๋ฌ์ด๋ฉฐ CORS๋ ์ด ์๋ฌ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ์์ด๋ผ๋ ๊ฒ์ด๋ค.
โถ๏ธ SOP์ ์ ์๊ฒจ๋๊ฒ ๋์์๊น?
๋์ผ ์ถ์ฒ ์ ์ฑ
์ ์ ์ฌ์ ์ผ๋ก ํด๋ก์ธ ์ ์๋ ๋ฌธ์๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก์จ ๊ณต๊ฒฉ๋ฐ์ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ์ค์ฌ์ค๋ค.
SOP์ ํตํด ํดํน ๋ฑ์ ์ํ์์ ๋ณด๋ค ๋ ์์ ํด์ง ์ ์๋ค๋ ๊ฒ์ด๋ค.
SOP ์ ์ฑ ์ด ์๋ ์ํฉ์์ ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ํ์ ๋ ธ์ถ๋ ์ ์๋ค.
- XSS (Cross-Site Scripting)
์ฌ์ฉ์๊ฐ ํน์ ์น ์ฌ์ดํธ๋ฅผ ์ ์ฉํ๋ ์ ์ ๋ ธ๋ ค, ์ ์ฑ ์ฝ๋๋ฅผ ์น ์ฌ์ดํธ์ ์ฌ์ด ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ - CSRF (Cross-Site Request Forgery)
ํน์ ์น ์ฌ์ดํธ๊ฐ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ฉํ๋ ์ํ๋ฅผ ๋ ธ๋ ค, ์ฌ์ฉ์๊ฐ ์์ ์ ์์ง์๋ ๋ฌด๊ดํ๊ฒ ๊ณต๊ฒฉ์๊ฐ ์๋ํ ํ์(์์ , ์ญ์ , ๋ฑ๋ก ๋ฑ)๋ฅผ ํน์ ์น ์ฌ์ดํธ์ ์์ฒญํ๊ฒ ํ๋ ๋ฐฉ๋ฒ
๐ CORS (Cross-Origin Resource Sharing)
๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (Cross-Origin Resource Sharing, CORS)๋ ์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ, ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ์ฑ ํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ ์ด๋ค.
โถ๏ธ CORS ๋์ ๋ฐฉ์
CORS์ ๋์ ๋ฐฉ์์๋ ํฌ๊ฒ ์ธ ๊ฐ์ง๊ฐ ์๋ค.
1. Preflight Request
์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ , OPTIONS
๋ฉ์๋๋ก ์ฌ์ ์์ฒญ์ ๋ณด๋ด ํด๋น ์ถ์ฒ ๋ฆฌ์์ค์ ์ ๊ทผ ๊ถํ์ด ์๋์ง๋ถํฐ ํ์ธํ๋ ๊ฒ
์ ์ด๋ฏธ์ง ํ๋ฆ๊ณผ ๊ฐ์ด, ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ์ ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ Preflight ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต ํค๋์ Access-Control-Arrow-Origin
์ผ๋ก ์์ฒญ์ ๋ณด๋ธ ์ถ์ฒ๊ฐ ๋์์ค๋ฉด ์ค์ ์์ฒญ์ ํ๊ฒ ๋๋ค.
๋ง์ฝ ์์ฒญ์ ๋ณด๋ธ ์ถ์ฒ๊ฐ ์ ๊ทผ ๊ถํ์ด ์๋ค๋ฉด ๋ธ๋ผ์ฐ์ ์์ CORS ์๋ฌ๋ฅผ ๋์ฐ๊ฒ ๋๊ณ , ์ค์ ์์ฒญ์ ์ ๋ฌ๋์ง ์๋๋ค.
Preflight Request๋ ์ ํ์ํ ๊น?
- ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๊ถํ ํ์ธ์ ํ ์ ์๊ธฐ ๋๋ฌธ์, ์ค์ ์์ฒญ์ ์ฒ์๋ถํฐ ํต์งธ๋ก ๋ณด๋ด๋ ๊ฒ ๋ณด๋ค ๋ฆฌ์์ค ์ธก๋ฉด์์ ํจ์จ์ ์ด๋ค.
- CORS์ ๋๋น๊ฐ ๋์ด์์ง ์์ ์๋ฒ๋ฅผ ๋ณดํธํ ์ ์๋ค. CORS ์ด์ ์ ๋ง๋ค์ด์ง ์๋ฒ๋ค์ SOP ์์ฒญ๋ง ๋ค์ด์ค๋ ์ํฉ์ ๊ณ ๋ คํ๊ณ ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์, ๋ค๋ฅธ ์ถ์ฒ์์ ๋ค์ด์ค๋ ์์ฒญ์ ๋ํ ๋๋น๊ฐ ๋์ด์์ง ์์๋ค.
์ด๋ฐ ์๋ฒ์ ๋ฐ๋ก ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ฉด, ์๋ต์ ๋ณด๋ด๊ธฐ ์ ์ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์๋ต์ ๋ฐ์ ํ์์ผ CORS ๊ถํ์ด ์๋ค๋ ๊ฒ์ ์ธ์งํ์ง๋ง, ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฌ๋ฅผ ๋์ด ํ์๋ ์ด๋ฏธ ์์ฒญ์ด ์ํ๋ ์ํ๊ฐ ๋๋ค.
ํ์ง๋ง CORS์ ๋๋น๊ฐ ๋์ด์์ง ์์ ์๋ฒ๋ผ๋ Preflight ์์ฒญ์ ๋จผ์ ๋ณด๋ด๊ฒ ๋๋ฉด, ๊ทธ ์์ฒญ์์ CORS ์๋ฌ๋ฅผ ๋์ฐ๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์คํ๋์ ์ ๋๋ Cross-Origin ์์ฒญ์ด ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๋ค. ์ด๋ฐ ์ด์ ๋ก Preflight ์์ฒญ์ด CORS์ ๊ธฐ๋ณธ ์ฌ์์ผ๋ก ๋ค์ด๊ฐ๊ฒ ๋์๋ค.
2. ๋จ์ ์์ฒญ (Simple Request)
๋จ์ ์์ฒญ์ ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋๋ฉด ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ ์๋ตํ๊ณ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ์ ๋งํ๋ค.
์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
GET
,HEAD
,POST
์์ฒญ ์ค ํ๋์ฌ์ผ ํ๋ค.- ์๋์ผ๋ก ์ค์ ๋๋ ํค๋ ์ธ์,
Accept
,Accept-Language
,Content-Language
,Content-Type
ํค๋์ ๊ฐ๋ง ์๋์ผ๋ก ์ค์ ํ ์ ์๋ค.Content-Type
ํค๋์๋application/x-www-form-urlencoded
,multipart/form-data
,text/plain
๊ฐ๋ง ํ์ฉ๋๋ค.
3. ์ธ์ฆ์ ๋ณด๋ฅผ ํฌํจํ ์์ฒญ (Credentialed Request)
์์ฒญ ํค๋์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ ๋ณด๋ด๋ ์์ฒญ์ด๋ค. ๋ฏผ๊ฐํ ์ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ์ถ์ฒ๊ฐ ๋ค๋ฅผ ๊ฒฝ์ฐ์๋ ๋ณ๋์ ์ค์ ์ ํ์ง ์์ผ๋ฉด ์ฟ ํค๋ฅผ ๋ณด๋ผ ์ ์๋ค. ์ด ๊ฒฝ์ฐ์๋ ํ๋ก ํธ, ์๋ฒ ์์ธก ๋ชจ๋ CORS ์ค์ ์ด ํ์ํ๋ค.
- ํ๋ก ํธ ์ธก์์๋ ์์ฒญ ํค๋์
withCredentials : true
๋ฅผ ๋ด์์ค์ผ ํ๋ค. - ์๋ฒ ์ธก์์๋ ์๋ต ํค๋์
Access-Control-Allow-Credentials : true
๋ฅผ ๋ด์์ค์ผ ํ๋ค. - ์๋ฒ ์ธก์์
Access-Control-Allow-Origin
์ ์ค์ ํ ๋, ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๋ค๋ ๋ป์ ์์ผ๋์นด๋(*
)๋ก ์ค์ ํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ค๋ฃจ๋ ๋งํผ ์ถ์ฒ๋ฅผ ์ ํํ๊ฒ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
โถ๏ธ CORS ์ค์ ๋ฐฉ๋ฒ
1. Node.js ์๋ฒ
const http = require("http");
const server = http.createServer((request, response) => {
// ๋ชจ๋ ๋๋ฉ์ธ
response.setHeader("Access-Control-Allow-Origin", "*");
// ํน์ ๋๋ฉ์ธ
response.setHeader("Access-Control-Allow-Origin", "https://codestates.com");
// ์ธ์ฆ ์ ๋ณด๋ฅผ ํฌํจํ ์์ฒญ์ ๋ฐ์ ๊ฒฝ์ฐ
response.setHeader("Access-Control-Allow-Credentials", "true");
});
2. Express ์๋ฒ
const cors = require("cors");
const app = express();
//๋ชจ๋ ๋๋ฉ์ธ
app.use(cors());
//ํน์ ๋๋ฉ์ธ
const options = {
origin: "https://codestates.com", // ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํ๋ ๋๋ฉ์ธ
credentials: true, // ์๋ต ํค๋์ Access-Control-Allow-Credentials ์ถ๊ฐ
optionsSuccessStatus: 200, // ์๋ต ์ํ 200์ผ๋ก ์ค์
};
app.use(cors(options));
//ํน์ ์์ฒญ
app.get("/example/:id", cors(), function (req, res, next) {
res.json({ msg: "example" });
});
Reference
MDN : ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (CORS)
Leave a comment