Code States
Front-end boost camp
Today
I
Learned
๐งฉ 36์ผ์ฐจ...
๐งฉ SOP
- Same-Origin Policy : ๋์ผ ์ถ์ฒ ์ ์ฑ
-> ๊ฐ์ ์ถ์ฒ์ ๋ฆฌ์์ค๋ง ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ค.
- ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ ๋ชจ๋๊ฐ ๊ฐ์์ผ ๋์ผํ ์ถ์ฒ๋ก ๋ณธ๋ค.

- SOP์ ์?
-- ์ ์ฌ์ ์ผ๋ก ํด๋ก์ธ ์ ์๋ ๋ฌธ์๋ฅผ ๋ถ๋ฆฌ, ๊ณต๊ฒฉ๋ฐ์ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ์ค์ฌ์ค
-- ํดํน๋ฑ์ ์ํ์์ ๋ณด๋ค ๋ ์์
-- ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์๋ ์ ์ฑ
๐งฉ CORS
- Cross-Origin-Resource Sharing : ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์
- HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ฌ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์
- ๋ธ๋ผ์ฐ์ ๋ SOP์ ์ํด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค ๊ณต์ ๋ฅผ ๋ง์ง๋ง
-- CORS๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๊ทผ ๊ถํ์ ์ป์
๐งฉ CORS ๋์ ๋ฐฉ์
โ๏ธ 1. ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ
- ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ , OPTIONS ๋ฉ์๋๋ก ์ฌ์ ์์ฒญ์ ๋ณด๋ด ํด๋น ์ถ์ฒ ๋ฆฌ์์ค์ ์ ๊ทผ ๊ถํ์ด ์๋์ง๋ถํฐ ํ์ธํ๋ ๊ฒ
- ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ์ ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ ๋ณด๋ด๊ณ , ์๋ต ํค๋์ Access-Control-Allow-Origin์ผ๋ก ์์ฒญ์ ๋ณด๋ธ ์ถ์ฒ๊ฐ ๋์์ค๋ฉด ์ค์ ์์ฒญ์ ๋ณด๋ โผ

- ๋ง์ฝ ์์ฒญ์ ๋ณด๋ธ ์ถ์ฒ๊ฐ ์ ๊ทผ ๊ถํ์ด ์๋ค๋ฉด?
-- ๋ธ๋ผ์ฐ์ ์์ CORS ์๋ฌ๋ฅผ ๋์ฐ๊ฒ ๋๊ณ , ์ค์ ์์ฒญ์ ์ ๋ฌ๋์ง ์์ โผ

- ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ด ํ์ํ ์ด์ ?
-- ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๊ถํ์ ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์ ์ค์ ์์ฒญ์ ์ฒ์๋ถํฐ ํต์งธ๋ก ๋ณด๋ด๋ ๊ฒ๋ณด๋ค ๋ฆฌ์์ค ์ธก๋ฉด์์ ํจ์จ์
-- CORS์ ๋๋น๊ฐ ๋์ด์์ง ์์ ์๋ฒ ๋ณดํธ ๊ฐ๋ฅ
-- ex) ๋ค๋ฅธ ์ถ์ฒ์์ ๋ค์ด์ค๋ ์์ฒญ์ ๋ํ ๋๋น๊ฐ ๋์ด์์ง ์์ ์๋ฒ์ ๋ฐ๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด, ์๋ต์ ๋ณด๋ด๊ธฐ ์ ์ ์ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ฒ ๋จ. ์๋ต์ ๋ฐ๊ณ ๋์์ผ CORS๊ถํ์ด ์์์ ์ธ์งํ์ง๋ง ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฌ๋ฅผ ๋์ด ํ์๋ ์ด๋ฏธ ์์ฒญ์ด ์ํ๋ ์ํ..! ์ํ!
โ๏ธ 2. ๋จ์ ์์ฒญ
- ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋๋ฉด ํ๋ฆฌํ๋ผ์ดํธ ์์ฒญ์ ์๋ตํ๊ณ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ
-- ์กฐ๊ฑด1. GET, HEAD, POST ์์ฒญ ์ค ํ๋์ฌ์ผ ํจ
-- ์กฐ๊ฑด2. ์๋์ผ๋ก ์ค์ ๋๋ ํค์ด ์ธ Acccept, Accept-Language, Content-Language, Content-Type ํค๋์ ๊ฐ๋ง ์๋์ผ๋ก ์ค์ ๊ฐ๋ฅ (Content-Type ํค๋์๋ application/x-www-form-urlencoded, multipart/form-data, text/plain ๊ฐ๋ง ํ์ฉ)
โ๏ธ 3. ์ธ์ฆ์ ๋ณด๋ฅผ ํฌํจํ ์์ฒญ
- ์์ฒญ ํค๋์ ์ธ์ฆ ์ ๋ณด๋ฅผ ๋ด์ ๋ณด๋ด๋ ์์ฒญ
- ์ถ์ฒ๊ฐ ๋ค๋ฅผ ๊ฒฝ์ฐ? ๋ณ๋์ ์ค์ ์ ํ์ง ์์ผ๋ฉด ์ฟ ํค๋ฅผ ๋ณด๋ผ ์ ์๋ค. ์ด ๊ฒฝ์ฐ์ ํด๋ผ์ด์ธํธ, ์๋ฒ ์์ธก ๋ชจ๋ CORS ์ค์ ์ด ํ์
- ์ฃผ์์ฌํญ
-- ํด๋ผ์ด์ธํธ ์ธก์์๋ ์์ฒญ ํค๋์ withCredentials : true๋ฅผ ๋ฃ์ด์ค์ผ ํจ
-- ์๋ฒ ์ธก์์๋ ์๋ต ํค๋์ Access-Comtrol-Allow-Credentials : true ๋ฅผ ๋ฃ์ด์ค์ผ ํจ
-- ์๋ฒ ์ธก์์ Access-Control-Allow-origin์ ์ค์ ํ ๋, ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๋ค๋ ๋ป์ ์์ผ๋์นด๋๋ก ์ค์ ํ๋ฉด ์๋ฌ ๋ฐ์, ์ถ์ฒ๋ฅผ ์ ํํ๊ฒ!
๐งฉ CORS ์ค์ ๋ฐฉ๋ฒ
โ๏ธ 1. Node.js ์๋ฒ
- Node.js๋ก ๊ฐ๋จํ HTTP ์๋ฒ๋ฅผ ๋ง๋ค ๊ฒฝ์ฐ, ๋ค์๊ณผ ๊ฐ์ด ์๋ต ํค๋ ์ค์ ๊ฐ๋ฅ
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 ์๋ฒ
- cors ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด ๋์ฑ ๊ฐ๋จํ๊ฒ CORS ์ค์ ๊ฐ๋ฅ
const cors = require("cors");
const app = express();
app.use(cors());
const options = {
origin: "https://codestates.com",
credentials: true,
optionsSuccessStatus: 200,
};
app.use(cors(options));
app.get("/example/:id", cors(), function (req, res, next) {
res.json({ msg: "example" });
});
๐งฉ ํ์ดํ๋ก๊ทธ๋๋ฐ ๊ณผ์ - Mini Node Server
const http = require("http");
const PORT = 4999;
const ip = "localhost";
const server = http.createServer((request, response) => {
console.log(
`http request method is ${request.method}, url is ${request.url}`
);
if (request.method === "OPTIONS") {
response.writeHead(200, defaultCorsHeader);
response.end();
}
if (request.method === "POST" && request.url === "/upper") {
let body = [];
request.on("data", (chunk) => {
body.push(chunk);
}).on("end", () => {
body = Buffer.concat(body).toString().toUpperCase();
response.end(body);
});
} else if (request.method === "POST" && request.url === "/lower") {
let body = [];
request.on("data", (chunk) => {
body.push(chunk);
}).on("end", () => {
body = Buffer.concat(body).toString().toLowerCase();
response.end(body);
});
} else {
response.statusCode = 400;
response.end();
}
response.writeHead(200, defaultCorsHeader);
response.end('hello mini-server sprints');
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Accept",
"Access-Control-Max-Age": 10,
};