[C/F TIL] 36์ผ์ฐจ - Web Server, CORS, SOP

mu-engยท2023๋…„ 6์›” 1์ผ
1

TIL (in boost camp)

๋ชฉ๋ก ๋ณด๊ธฐ
35/53
post-thumbnail

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, // ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials ์ถ”๊ฐ€
  optionsSuccessStatus: 200, // ์‘๋‹ต ์ƒํƒœ 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();
      // ์—ฌ๊ธฐ์„œ `body`์— ์ „์ฒด ์š”์ฒญ ๋ฐ”๋””๊ฐ€ ๋ฌธ์ž์—ด๋กœ ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค.
      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();
      // ์—ฌ๊ธฐ์„œ `body`์— ์ „์ฒด ์š”์ฒญ ๋ฐ”๋””๊ฐ€ ๋ฌธ์ž์—ด๋กœ ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค.
      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,
};
profile
[๋ฌด์—ฅ์ผ๊ธฐ] ๋ฌด์—ฅ,,, ๋‚ด๊ฐ€ ๋จธ์จ์ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋  ์ˆ˜ ์ด์“ฐ๊นŒ,,,

0๊ฐœ์˜ ๋Œ“๊ธ€