본문 바로가기

개념정리

12/30[TIL] Server & Node

서버가 CORS를 허용하기 위해 HTTP 헤더에는 목적들이 있는데 

1
2
3
4
5
6
const defaultCorsHeaders = {
  "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 // Seconds.
};
cs

allow-origin은 허용할 오리진을 뜻하며 요청을 보내는 프런트엔드 주소와 백엔드 주소가 다르게 되면 CORS 에러가 난다. 그래서 여기에는 프런트엔드 주소를 적어주어야 한다. 물론 프로토콜이나 도메인, 포트 중 하나만 달라도 CORS 에러가 나는 것은 변함이 없다. 물론 위의 그림에서는 *(와일드카드)를 넣어주어 다 허용해 주었으나 그렇게 되면 보안이 취약해진다.

allow-method은 허용할 메소드

allow-header은 허용할 헤더

max-age는 얼마나 오랫동안 신뢰할 수 있는 origin인지를 초 단위로 표현한 것이다.

 

 

기존에 http 모듈을 통해 서버를 만들었지만 express 서버 프레임워크를 사용하면 훨씬 편리하게 만들 수 있다.

 

http 모듈을 통해 서버를 만들었던 것을 master 브랜치에 만들어 두어 이번에는 express라는 브랜치를 만들어 거기에서 express 서버 프레임워크를 사용하여 리팩터링 해보고자 한다.

1
2
3
$ git branch [브랜치명] //생성할 브랜치명(express)
 
$ git checkout [브랜치명] //전환할 브랜치명(express)
cs

내가 나중에 express 브랜치에서 전에 작업을 하였던 master 브랜치를 전환하고자 하면 기존에 express 브랜치에서의 $ git add와 커밋을 진행해주어야 전환이 가능하다.

 

기존에 http모듈을 사용한 서버 구현은 아래와 같이 코드가 길지만 express를 사용하게 되면 훨씬 효율적인 코드로 바뀔 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....//생략//
const
 requestHandler = function (request, response) {
  const { headers, method, url, body } = request; // 구조 분해 할당 사용
 
  if (method === "OPTIONS") { //CORS OPTIONS 설정
    response.writeHead(200, defaultCorsHeaders);
    response.end(); //response는 반드시 end 해주기!
  } else if (method === "GET" && url === "/messages") {//GET 요청시 결과값(data) 받아오기!
 
    response.writeHead(200, defaultCorsHeaders);
    response.end(JSON.stringify(data)); //JSON.stringify 잊지 않기!
 
  } else if (method === "POST" && url === "/messages") {//POST !! 
    let body = ""//일단 바디를 선언해주고...
 
....//생략//
 
    })
  } else {
    response.writeHead(404);
    response.end();
  }
 
cs

 

아래와 같이 express를 사용하게 되면 여러 가지 필요한 것들을 선언하고 난 후 훨씬 간결한 코드로도 같은 결과를 낼 수 있다.

get / post 요청이 간략해진 것과 cors 요청, 그리고 기존에 응답 부분에 json.stringify를 사용했던 것을 send에 data를 그냥 바로 넣음으로써 바로 해결되는 것을 알 수 있었다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const express = require('express'// 모듈불러오기! cf(경로일 시엔 파일불러오기 확장자 생략가능!)
const app = express() //웹서버 생성
const cors = require('cors')
const port = 3000
 
app.use(cors({
    origin: ''//특정 오리진적용할 경우!!
}))
 
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json()
 
...//생략//
 
app.get('/messages', (req, res) => { 
    res.status(200).send(data);
})
 
app.post('/messages', jsonParser, function (req, res) {
 
    console.log(req.body)
    data.results.push(req.body);
    res.status(201).send(data)
    // req.body에는 JSON의 형태로 payload가 담겨져 있습니다.
})
...//생략//
cs

물론 이 것 말고도 express의 장점은 정말 많다. 자체 라우터 기능을 제공하므로, 라우터를 활용하면 지금 위에서 사용한 코드보다 훨씬 직관적인 코딩을 할 수 있으며 지원하는 편리한 미들웨어도 많기 때문에 정말 유용하다. 

 

가장 단순한 미들웨어는 logger이다. 말 그대로 로거는 디버깅이나, 서버 관리에 도움이 되기 위해 console.log를 적절하게 찍어주는 역할을 한다.

 

그리고 순수 node.js 코드로 HTTP body(payload)를 받을 때에는 Buffer를 조합해서 다소 복잡한 방식으로 body를 얻어내야 했는데 이를 도와주는 body-parser 미들웨어

 

또 http 모듈에서는 까다로웠던 cors 설정을 편리하게 해주는 cors 미들웨어

 

이 것 말고도 토큰이 있는지 여부를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어도 존재한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const express = require('express');
const app = express();
 
const myLogger = function (req, res, next) {
  console.log('LOGGED'); // 이 부분을 req, res 객체를 이용해 고치면, 여러분들은 모든 요청에 대한 로그를 찍을 수 있습니다.
  next();
};
 
app.use(myLogger);
 
app.get('/', function (req, res) {
  res.send('Hello World!');
});
 
app.listen(3000);
cs

'개념정리' 카테고리의 다른 글

1/5[TIL]React(2)  (0) 2021.01.05
1/4[TIL]React(1)  (0) 2021.01.04
12/15[TIL]Deploy  (0) 2020.12.15
12/11[TIL]Authentication(3)  (0) 2020.12.11
12/10[TIL]Authentication(2)  (0) 2020.12.10