[TIL] Unit 10. Web Server ๊ธฐ์ดˆ

string_mainยท2022๋…„ 6์›” 16์ผ
0

Node.js

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

๐ŸŒฑ SOP(Same-Origin Policy)


  • ์ •์˜ : Same-Origin Policy์˜ ์•ฝ์ž๋กœ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์„ ๋œปํ•œ๋‹ค. ํ•œ ๋งˆ๋””๋กœ โ€˜๊ฐ™์€ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋งŒ ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹คโ€™๋ผ๋Š” ์ •์ฑ…!

  • ์ถœ์ฒ˜(Origin) ๊ธฐ์ค€ :

    • https://www.codestates.com vs http://www.codestates.com
      โ‡’ ํ”„๋กœํ† ์ฝœ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹˜.
    • https://urclass.codestates.com vs https://codestates.com
      โ‡’ ํ˜ธ์ŠคํŠธ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹˜.
    • http://codestates.com:81 vs http://codestates.com
      โ‡’ port๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹˜. (http ํ”„๋กœํ† ์ฝœ์˜ ๊ธฐ๋ณธ ํฌํŠธ๋Š” 80)
  • ํ•„์š”์„ฑ : ์ž ์žฌ์ ์œผ๋กœ ํ•ด๋กœ์šธ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ๊ณต๊ฒฉ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ค„์—ฌ์ค€๋‹ค. ์ฆ‰, ํ•ดํ‚น ๋“ฑ์˜ ์œ„ํ˜‘์—์„œ ๋ณด๋‹ค ๋” ์•ˆ์ „ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

    ๋„ค์ด๋ฒ„์— ๋กœ๊ทธ์ธํ•ด์„œ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

    ์„œ๋น„์Šค ์ด์šฉ์ค‘์ด ์•„๋‹ˆ๋”๋ผ๋„ ๋กœ๊ทธ์•„์›ƒ์„ ๊นœ๋นกํ–ˆ๊ฑฐ๋‚˜ ์ž๋™ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์œผ๋กœ ์ธํ•ด ๋ธŒ๋ผ์šฐ์ €์— ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ๋‚จ์•„์žˆ๋Š” ์ƒํƒœ์—์„œ ๋‚˜์˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋…ธ๋ฆฌ๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์— ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด?

    ํ•ด์ปค๋Š” ๋‚˜์˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ ๋„ค์ด๋ฒ„์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

๐ŸŒฑ CORS (Cross-Origin Resource Sharing)


์ด์ œ SOP์ด ์ค‘์š”ํ•œ ๊ฑด ์•Œ๊ฒ ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ...๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ์ผ์€ ๋„ˆ๋ฌด๋‚˜๋„ ๋งŽ๋‹ค. ๋‹น์žฅ ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ๋„ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋ฅผ ๋”ฐ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด ์ถœ์ฒ˜๊ฐ€ ๋‹ฌ๋ผ์ง€๊ฒŒ ๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์›น์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ ์ค‘์— ๋„ค์ด๋ฒ„ ์ง€๋„ api๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? github ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? ๋ชจ๋‘ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ผ์ธ๋ฐ, ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์„๊นŒ?

  • ์ •์˜ : Cross-Origin Resource Sharing์˜ ์•ฝ์ž๋กœ ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ๋œปํ•œ๋‹ค. ์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ด๋‹ค.

๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ–ˆ์ง€๋งŒ SOP ๋•Œ๋ฌธ์— ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. CORS ์„ค์ •์„ ํ†ตํ•ด ์„œ๋ฒ„์˜ ์‘๋‹ต ํ—ค๋”์— โ€˜Access-Control-Allow-Originโ€™์„ ์ž‘์„ฑํ•˜๋ฉด ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ผ๋Š” ์—๋Ÿฌ์ด๋‹ค. ์œ„์™€ ๊ฐ™์€ ์—๋Ÿฌ๋Š” CORS๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค!

๐ŸŒฟ CORS ๋™์ž‘ ๋ฐฉ์‹

  1. ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ (Preflight Request) :
    ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „, OPTIONS ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์ „ ์š”์ฒญ์„ ๋ณด๋‚ด ํ•ด๋‹น ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€๋ถ€ํ„ฐ ํ™•์ธํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‘๋‹ต ํ—ค๋”์˜ Access-Control-Allow-Origin์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ ์ถœ์ฒ˜๊ฐ€ ๋Œ์•„์˜ค๋ฉด ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค. (์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†์œผ๋ฉด CORS ์—๋Ÿฌ ๋ฐœ์ƒ)
  • ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์€ ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋ฏธ๋ฆฌ ๊ถŒํ•œ ํ™•์ธ์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ถŒํ•œ์ด ์—†๋Š” ์š”์ฒญ์„ ๋ฏธ๋ฆฌ ๊ฑฐ๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฆฌ์†Œ์Šค ์ธก๋ฉด์—์„œ ํšจ์œจ์ ์ด๋‹ค.
  1. ๋‹จ์ˆœ ์š”์ฒญ (Simple Request) :
    ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜๋ฉด ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ์ƒ๋žตํ•˜๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ
  • ๋‹จ์ˆœ ์š”์ฒญ ์กฐ๊ฑด (๋ชจ๋‘ ๋งŒ์กฑ์‹œํ‚ค๊ธฐ๋Š” ์–ด๋ ค์›€) :
    • GET, HEAD, POST ์š”์ฒญ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.
    • ์ž๋™์œผ๋กœ ์„ค์ •๋˜๋Š” ํ—ค๋” ์™ธ์—, Accept, Accept-Language, Content-Language, Content-Type ํ—ค๋”์˜ ๊ฐ’๋งŒ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. (Content-Type ํ—ค๋”์—๋Š” application/x-www-form-urlencoded, multipart/form-data, text/plain ๊ฐ’๋งŒ ํ—ˆ์šฉ)
  1. ์ธ์ฆ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ (Credentialed Request) :
    ์š”์ฒญ ํ—ค๋”์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๋Š” ์š”์ฒญ. ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ์—๋Š” ๋ณ„๋„์˜ ์„ค์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์—†๋‹ค. (๋ฏผ๊ฐ ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ) ์ด ๊ฒฝ์šฐ์—๋Š” ํ”„๋ก ํŠธ, ์„œ๋ฒ„ ์–‘์ธก ๋ชจ๋‘ CORS ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.
  • ํ”„๋ก ํŠธ ์ธก์—์„œ๋Š” ์š”์ฒญ ํ—ค๋”์— withCredentials : true ๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•จ.
  • ์„œ๋ฒ„ ์ธก์—์„œ๋Š” ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials : true ๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•จ.
  • ์„œ๋ฒ„ ์ธก์—์„œ Access-Control-Allow-Origin ์„ ์„ค์ •ํ•  ๋•Œ, ๋ชจ๋“  ์ถœ์ฒ˜๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๋œป์˜ ์™€์ผ๋“œ์นด๋“œ(*)๋กœ ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” ๋งŒํผ ์ถœ์ฒ˜๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๐ŸŒฟ CORS ์„ค์ • ๋ฐฉ๋ฒ•

  1. 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");
})
  1. Express ์„œ๋ฒ„ : 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" });
});

์ด ์™ธ ๋‹ค์–‘ํ•œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋„, ํ—ค๋”์˜ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•๋งŒ ์•Œ๋ฉด CORS ์„ค์ •์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒฑ Node Server


  • Node.js๋Š” HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ณด๋‚ด ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์›น ์„œ๋ฒ„(Web Server)๋ผ๊ณ  ํ•œ๋‹ค.
  • Node.js์—์„œ HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด HTTP ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.

๐ŸŒฑ Express


MERN stack์€ JavaScript ์ƒํƒœ๊ณ„์—์„œ ์ธ๊ธฐ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ธ MongoDB, Express, React, Node.js๋ฅผ ์ง€์นญํ•˜๋Š” ๋‹จ์–ด์ด๋‹ค. ๊ทธ ์ค‘ Express๋ฅผ ์•Œ์•„๋ณด์ž!

  • ์ •์˜ : Node.js ํ™˜๊ฒฝ์—์„œ ์›น ์„œ๋ฒ„, ๋˜๋Š” API ์„œ๋ฒ„๋ฅผ ์ œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์ธ๊ธฐ ์žˆ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, Node.js HTTP ๋ชจ๋“ˆ๋กœ ์ž‘์„ฑํ•œ ์„œ๋ฒ„์™€์˜ ์ฐจ์ด์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    • ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋ผ์šฐํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๐ŸŒฟ Express Server

  1. Express ์„ค์น˜
npm install express
  1. ๊ฐ„๋‹จํ•œ ์›น ์„œ๋ฒ„ ์‹œ์ž‘ํ•˜๊ธฐ
// ์‘๋‹ต์œผ๋กœ 'Hello World!' ๋ฅผ ๋ณด๋‚ด๋Š” Express ์„œ๋ฒ„
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
  1. ๋ฉ”์„œ๋“œ์™€ url์— ๋”ฐ๋ผ ๋ถ„๊ธฐ(Routing)ํ•˜๊ธฐ
  • ๋ผ์šฐํŒ…(Routing) : ๋ฉ”์„œ๋“œ์™€ url(/lower, /upper ๋“ฑ)๋กœ ๋ถ„๊ธฐ์ ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์œผ๋กœ, Express๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด์—์„œ ๋ผ์šฐํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
// ์ˆœ์ˆ˜ Node.js ๋ผ์šฐํŒ… ์ฝ”๋“œ
const requestHandler = (req, res) => {
  if(req.url === '/lower') {
    if (req.method === 'GET') {
      res.end(data)
    } else if (req.method === 'POST') {
      req.on('data', (req, res) => {
        // do something ...
      })
    }
  }
}

// Express ๋ผ์šฐํŒ… ์ฝ”๋“œ
const router = express.Router()

router.get('/lower', (req, res) => {
  res.send(data);
})

router.post('/lower', (req, res) => {
  // do something
})

๐ŸŒฟ ๋ฏธ๋“ค์›จ์–ด (Middleware)

๋ฏธ๋“ค์›จ์–ด(Middleware)๋Š” ๋ง ๊ทธ๋Œ€๋กœ ํ”„๋กœ์„ธ์Šค ์ค‘๊ฐ„์— ๊ด€์—ฌํ•˜์—ฌ ํŠน์ • ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฑฐ์ณ๊ฐ€๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋˜ํ•œ, ๋ฏธ๋“ค์›จ์–ด๋Š” ์ž๋™์ฐจ ๊ณต์žฅ์˜ ๊ณต์ •๊ณผ ๋น„์Šทํ•˜๋‹ค!

โžก๏ธ ์š”์ฒญ(Request)์— ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋”ํ•˜๊ฑฐ๋‚˜, ๋ฌธ์ œ๊ฐ€ ๋ฐœ๊ฒฌ๋œ ๋ถˆ๋Ÿ‰ํ’ˆ์„ ๋ฐ–์œผ๋กœ ๊ฑท์–ด๋‚ด๋Š” ์—ญํ• ์„ ํ•ด์ฃผ๋Š”๋ฐ, ์ด๊ฒƒ์ด Express์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด๋‹ค.

  • ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒํ™ฉ
  1. POST ์š”์ฒญ ๋“ฑ์— ํฌํ•จ๋œ body(payload)๋ฅผ ๊ตฌ์กฐํ™”ํ•  ๋•Œ(์‰ฝ๊ฒŒ ์–ป์–ด๋‚ด๊ณ ์ž ํ•  ๋•Œ)

Node.js๋กœ HTTP ์š”์ฒญ body๋ฅผ ์–ป์œผ๋ ค๋ฉด, Buffer๋ฅผ ์กฐํ•ฉํ•ด์„œ ๋‹ค์†Œ ๋ณต์žกํ•œ ๋ฐฉ์‹์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body ๋ณ€์ˆ˜์—๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ payload๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.
});

ํ•˜์ง€๋งŒ, Express์—์„œ๋Š” body-parser ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ด์šฉํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

npm install body-parser
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();
// ์ƒ๋žต
app.post('/users', jsonParser, function (req, res) {
})

Express v4.16.0 ๋ถ€ํ„ฐ๋Š” ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋”ฐ๋กœ ์„ค์น˜ํ•˜์ง€ ์•Š๊ณ  ๋‚ด์žฅ ๋ฏธ๋“ค์›จ์–ด์ธ express.json()์„ ์‚ฌ์šฉํ•œ๋‹ค!

const jsonParser = express.json();

app.post('/api/users', jsonParser, function (req, res) {
  // ์ƒ๋žต
})
  1. ๋ชจ๋“  ์š”์ฒญ/์‘๋‹ต์— CORS ํ—ค๋”๋ฅผ ๋ถ™์—ฌ์•ผ ํ•  ๋•Œ

Node.js HTTP ๋ชจ๋“ˆ์„ ์ด์šฉํ•œ ์ฝ”๋“œ์— CORS ํ—ค๋”๋ฅผ ๋ถ™์ด๋ ค๋ฉด, ์‘๋‹ต ๊ฐ์ฒด์˜ writeHead ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ๋ผ์šฐํŒ… ๋งˆ๋‹ค ๋งค๋ฒˆ ํ—ค๋”๋ฅผ ๋„ฃ์–ด์คฌ์–ด์•ผ ํ–ˆ๋‹ค...)

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
};
// ์ƒ๋žต
if (req.method === 'OPTIONS') {
  res.writeHead(201, defaultCorsHeader);
  res.end()
}

Express์—์„œ๋Š” cors ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค!

npm install cors
// ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด CORS ์ ์šฉ
const cors = require('cors');
app.use(cors());

// ํŠน์ • ์š”์ฒญ์— ๋Œ€ํ•ด CORS ์ ์šฉ
const cors = require('cors')

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})
  1. ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด url์ด๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ™•์ธํ•  ๋•Œ (app.use() ์‚ฌ์šฉ)
const express = require('express');
const app = express();

const myLogger = function (req, res, next) {
  console.log('LOGGED');
  next();
};

app.use(myLogger);

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);
  1. ์š”์ฒญ ํ—ค๋”์— ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋Š”์ง€ ํ™•์ธํ•  ๋•Œ (์ถ”ํ›„์— ๋‹ค์‹œ ๋‹ค๋ฃฐ ์˜ˆ์ •)
// ํ† ํฐ์„ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด
app.use((req, res, next) => {
  // ํ† ํฐ์ด ์žˆ๋Š”์ง€ ํ™•์ธ, ์—†์œผ๋ฉด ๋ฐ›์•„์ค„ ์ˆ˜ ์—†์Œ.
  if(req.headers.token){
    req.isLoggedIn = true;
    next();
  } else {
    res.status(400).send('invalid user')
  }
})

๐ŸŒฑ ์•Œ๊ฒŒ๋œ ์  & ๋Š๋‚€ ์ 


  • ๊ณต์‹๋ฌธ์„œ๋ฅผ ๊ผผ๊ผผํžˆ ๋ณด์ž! ๊ทธ๊ฒƒ์€ ์ •๋‹ต์ง€์™€ ๋‹ค๋ฆ„์—†๋‹ค.
  • ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์›ํ™œํžˆ ์ดํ•ดํ•˜๋ ค๋ฉด ์‹œ๊ฐ„๋‚  ๋•Œ ์˜์–ด ๊ณต๋ถ€ํ•˜๋ฉด ์ข‹์„ ๋“ฏ.

๐ŸŒฑ Check List


  • SOP์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • CORS์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • CORS ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • CORS ์„ค์ • ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•œ๋‹ค.
  • Express๋กœ ๊ฐ„๋‹จํ•œ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ดํ•ด, ์‚ฌ์šฉ, ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Node Server๋ฅผ Express๋กœ ๋ฆฌํŒฉํ† ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒฑ ์ถ”๊ฐ€ ํ•™์Šต


  • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์—ฐ๋™ํ•ด๋ณด๊ธฐ

| ์ฐธ๊ณ ์ž๋ฃŒ |

profile
FE developer

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