[JavaScript] TWIL : CORS와 Server 구축(Node.js, Express) (20/11.13~11.17)

정빈·2020년 11월 21일
0
post-custom-banner

Node.js환경에서 Server를 2가지 방법으로 구축하는 스프린트를 진행했다.

  1. 먼저, Node.js의 http 모듈을 사용해서 구축한다. (basic)
  2. 그 다음, express라는 프레임워크를 사용해서 더 쉽게 구축하는 방법으로 리팩토링을 한다.

Server 구축하기

1. CORS (Cross-Origin Resource Sharing)

먼저, Server를 구축하기 전 CORS라는 개념을 알아야 할 필요가 있다.
CORS란, 서로 다른 origin(출처)을 가진 Client와 Server가 통신을 하는 경우를 뜻한다.

여기서 origin이란, 우리가 흔히 알고있는 server의 주소인 url을 뜻하는데,
url은 protocol, host, path 등 많은 요소로 이루어져있는데, 기본적으로 protocol과 host 중 하나라도 다르면 다른 origin으로 취급한다.

(출처 : MDN CORS)

그림처럼, origin이 domain-a.com인 Client에서 domain-b.com의 Web Server에 data 요청을 하면, Browser에 의해 자동으로 CORS 요청으로 통신하게 된다. (host가 다른 경우)
보안 상의 이유로, Browser는 요청을 받은 Server가 허용하는 외부(교차) 출처를 자체적으로 확인한다.
허용된 출처면 Server의 응답을 올바르게 Client에게 전달하고, 허용되지 않은 출처면 Server의 응답을 자체적으로 폐기하고 error를 띄운다.
그러니, 각각의 Server들은 response에 본인들이 허용할 외부 origin을 header에 명시해서 Browser에 알려줄 수 있도록 구축해야한다. 객체 형식으로 인자에 넘겨주면 된다.

보통 Client의 cross-site 요청은 preflighted 형식(예비 요청)으로 보내진다. 자신이 허용된 origin인지 먼저 확인을 하게 되는데, Client입장에서도 cross-site 요청은 자신들의 user 데이터에 영향을 줄 수 있기 때문에 서로에게 필요한 절차라고 볼 수 있다. 예비 요청에서 확인을 해서 허용을 확인하면, 본 요청과 응답이 자동으로 이루어진다.
예비 요청없이 단순 요청으로 바로 요청을 날려버릴 수도 있지만, 단순 요청의 요건이 웹 구조상 충족시키기 어려워 실질적으로 어려운 요청이다. 인증된 요청(Credentialed Request)을 보내는 것이 아니라면, 일반적으로 예비요청으로 선 확인하는 과정이 이루어진다고 볼 수 있겠다.

여기에서 CORS에 관련해서 좋은 글을 읽어볼 수 있다. 나 역시 이 블로깅을 하며 해당 글을 많이 참고했다.
(글 추천 해주신 IM24 동기님 감사합니다🙌🏻)

2. Node.js의 http 모듈 이용하기

가장 기본적인 방법으로, Node.js에서 http 모듈을 사용해서 Server를 구축할 수 있다.

require로 http 모듈을 불러와서, http.createServer(callback)로 request와 response를 핸들링하는 callback을 구축할 수 있다.

callback함수는 request와 response를 인자로 받으며, request의 정보에 접근해 분기하여 그에 알맞은 response를 보낼 수 있다.
아래의 예제는 request의 메서드가 OPTION, GET, POST 인 경우를 분기해 작성하는 수도코드이다.

const http = require("http"); // require 구문으로 http 모듈을 불러온다.

http.createServer(function (request, response) {
  // 1. request의 method가 OPTION 인 경우 (preflighted 요청)
  // writeHead 메서드를 이용해 reponse로 상태코드와 *CORS 허용 정보를 담긴 객체*를 전달
  
  // 2. request의 method가 GET 인 경우 (preflighted 통과)
  // 마찬가지로 응답 head에 상태코드와 *CORS 허용 정보를 담긴 객체*를 담고,
  // data를 JSON형태로 전달
  
  // 3. request의 method가 POST 인 경우 (preflighted 통과)
  // 조각으로 들어오는 request의 data를 모아 JSON형태로 가공후 Server에 저장
  // 응답 head에 상태코드와 *CORS 허용 정보를 담긴 객체*를 담고
  // 전달받은 data을 본 응답으로 보내주든, 완료 메세지를 보내주든 그건 서버 구축자 마음
  
  // + url을 확인해 router를 분기 할 수도 있다.
  
  // 위의 경우가 아닌 모든 다른 경우들은 응답 head에 4XX대 상태코드와 함께 에러처리
  
  // Server 실행은 listen 메서드로!
});

3. Express 프레임워크 이용하기

Express는 자체 라우터를 제공하고, 미들웨어(데이터를 공정하는 중간처리)를 붙이기 쉬워 웹을 구축할 때 사용되는 인기있는 프레임워크이다.

(출처 : expressjs.com)

위 그림은 endpoint가 /이면서, GET 요청을 받았을 때에, 사용하는 미들웨어이다.
각 요청에 대해 request를 원하는 대로 공정할 수 있으며, 이번에 사용했던 body-parser 미들웨어CORS 미들웨어는 데이터 처리를 굉장히 간단하게 만들어 주었다.

Express를 이용해서는 http를 이용한 구축보다 훨씬 간단했다.

// Express와  middleWare 사용법
const app = express(); // === http.createServer()

app.use(middleWare) // use 메서드 : 모든 요청에 대해 middleWare 적용

app.middleWare를 걸고싶은 메서드(`/${anyRouter}`, ...원하는 middleWare(req, res, next));

// 이렇게 해당 요청에 대한 미들웨어를 적용해 req(request)를 가공하고 status, send 메서드를 이용해 res(response)를 보내면 된다.

// Server 실행은 listen 메서드로!


이렇게 http 모듈과 Express 프레임워크를 이용해 Server를 직접 구축하는 스프린트를 마무리했다. Client와 Server를 통신하도록 만들기 위해 많은 개념들을 한번에 접해야해서 내용을 어떻게 정리해야할지 고민하는 시간이 길어져 블로깅이 밀렸었다. 블로깅을 하면서 이렇게 골머리가 아프기는 처음이다. 학습한 모든 내용을 다룰 수 없어 최소한의 내용으로 간단하게 블로깅을 하고 일단 넘어가기로 했다.
과제도 해야하고, 이 다음의 스프린트들이 또 기다리고 있어 마냥 매달릴 수 없었다. 속도를 따라가야했기 때문에 T.T 하지만 웹 구조에 있어서 빠질 수 없는 중요한 개념들이니, soloDay에 내용 보충을 더 할 수 있도록 해야겠다. 💪🏻

profile
Back-end. You'll Never Walk Alone.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 1월 2일

짱입니다!

답글 달기