본문 바로가기

Node.js

1. http (서버제작 level 1) [express]

 

노드는 JS 실행기이다.
서버가 아니다.
다만, 서버를 돌릴 수 있는 코드를 작성해 두면 노드가 서버를 실행해준다.
-ZoroCho❤️-

 

 

1. 서버와 클라이언트

클라이언트 : 요청(request)을 서버로 보내는 장치, 프로그램
서버 : 요청을 처리하고, 응답(response)을 클라이언트에 제공하는 시스템

 

클라이언트와 서버간의 원활한 소통을 위해서는 약속된 공통의 언어가 필요하다.

이것이 바로 http 프로토콜(규약)이다.

 

2. 프로토콜 http

HTTP : Hyper Text Transfer Protocol, 하이터텍스트(HTML) 문서를 교환하기 위해 만들어진 프로토콜

 

http는 웹상에서 네트워크로 서버간 통신할때 어떤 형식으로 서로 통신할지 미리 규정해 놓은 약속으로 볼 수 있다.

http는 TCP/IP기반으로 되어있다.

http는 기본적으로 요청/응답 구조로 되어있다. (클라이언트가 요청하면 서버가 응답한다.)

 

2.1 요청 메시지

http Request Message는 공백을 제외하고 3가지 부분으로 구성된다.

(공백은 headers와 body를 구분한다.)

a. start line : 시작 부분 (1행)

  1. http method : 요청의 의도
  2. request target : 목표 주소
  3. http version : http버전 (버전에 따라 요청메시지 구조나 데이터가 다를 수 있다.)

b. headers : 추가 정보 부분

  1. Host : 요청하려는 서버 호스트 이름과 포트번호
  2. Accept : 클라이언트가 처리 가능한 미디어 타입 종류 나열
  3. Cookie : 쿠키 값이 key-value로 표현된다.
  4. 등...

c. body : 전송하는 데이터를 담고 있는 부분. 전송데이터가 없다면(get요청) 비어있다. 보통 post요청일 경우, HTML 폼 데이터가 포함되어 있다.

 

 

2.2 요청 메서드 종류

GET : 서버자원을 가져오는 메서드

POST : 서버자원을 새로 등록하는 메서드(애매한 경우 여기)

PUT : 서버자원을 전체 수정하는 메서드

PATCH : 서버자원을 부분 수정하는 메서드

DELETE : 서버자원을 삭제하는 메서드

 

2.3 응답 메시지

http Response Message도 공백을 제외하고 3가지 부분으로 구성된다. (요청과 동일)

(공백은 headers와 body를 구분한다.)

 

a. status line : 시작 부분 (1행)

  1. http version: http버전 (버전에 따라 응답메시지 구조나 데이터가 다를 수 있다.)
  2. status code : 처리결과를 나타내는 코드
  3. status text : 처리 결과의 이유(reason phrase)

b. headers : 추가 정보 부분 (요청과 동일. 다만 부분적으로 응답에서 안쓰이거나 응답에서만 쓰이는 것들이 있다. (User-Agent > Server) )

 

c. body : 전송하는 데이터를 담고 있는 부분. 전송데이터가 없다면 비어있다. (응답이라고 꼭 body에 무언가 있다 X)

 

 

2.4 http 상태코드 종류

writeHead 메서드에 첫번째 인수로 넣은 값이다.

요청에 대해 성공했는지 실패했는지를 알려준다.

 

a. 2XX : 성공, 200(성공), 201(작성됨) 

b. 3XX : 리다이렉션(다른 페이지로 이동), 어떤 주소를 입력했는데 다른 주소의 페이지로 넘어갈 때, 301(영구이동), 302(임시이동)

c. 4XX : 오류, 요청 자체에 오류가 있을 때 표시, 401(권한없음), 403(금지됨), 404(찾을 수 없음)

d. 5XX : 오류, 서버에 오류가 있을 때 표시, 요청은 제대로 왔지만 서버에 오류가 생겼을 때 표시, res.writeHead를 통해서 보내는 것이 아닌 에러발생시 서버가 알아서 5XX대 코드를 보냄, 500(내부서버 오류), 502(불량 게이트웨이), 503(서비스 사용할 수 없음)

 

3. REST API

서버를 코딩하는 입장에서 주소를 정해줘야 한다.

주소를 정할때 주로 REST API를 따른다.

REST API는 일종의 주소를 정하는 규칙이다.

 

RESTful API : REST API를 사용한 주소 체계를 이용하는 서버

 

4. 모듈 http

노드의 모듈 http는 내장모듈이다.

모듈 http를 사용하여 서버를 제작할 수 있다.

 

const http = require("http");

// 서버 생성
const server = http.createServer((req, res) => {
    res.write("<h1>Hello Node!</h1>");
    res.write("<p>Hello server</p>");
    res.end("<p>Hello Samdasoo</p>");
});

// 서버 8080번 포트로 실행 (서버를 프로세스에 올려주기)
    .listen(8080);
server.on("listening", () => {
    console.log("8080번 포트에서 서버가 대기 중입니다.");
});

// 에러처리 (http서버도 비동기)
server.on("error", (error) => {
    console.log(error);
});

 

+ 서버는 코드 수정이 자동으로 반영되지 않는다. 코드 수정 후 서버 재시작이 필요하다.

+ 하나의 도메인에 포트번호만 바꾸면 여러개의 프로그램을 동시에 연결해 놓을 수 있다.

 

fs모듈을 사용하여 읽어 온 html파일을 클라이언트에 전달할 수도 있다.

const http = require("http");
const fs = require("fs").promises;

// 서버 생성
const server = http.createServer(async (req, res) => {
    try {
    	// writeHead : 헤더에 입력하는 메서드, charset=utf-8 : "나 한글쓸거야"
    	res.writeHead(200, { 'Content-Type' : 'text/html; charset=utf-8' });
        // fs를 사용해 html파일 읽어오기
        const data= await fs.readFile("./⭐.html");
        res.end(data);
    } catch (error) {
    	console.error(err);
        res.writeHead(200, { 'Content-Type' : 'text/html; charset=utf-8' });
        res.end(err.message);
    }
});

// 서버 8080번 포트로 실행 (서버를 프로세스에 올려주기)
    .listen(8080);
server.on("listening", () => {
    console.log("8080번 포트에서 서버가 대기 중입니다.");
});

// 에러처리 (http서버도 비동기)
server.on("error", (error) => {
    console.log(error);
});

 

 

5. 쿠키와 세션

쿠키와 세션은 http프로토콜 때문에 필요하다.

http프로토콜 탓이다.

 

http프로토콜은 두가지 특성을 가진다.

첫번째 특성은 비연결지향(connectionless)이다.

클라이언트가 보낸 요청에 서버가 응답하게 되면 서로간의 연결이 끊기는 것이다.

두번째 특성은 상태정보유지않함(stateless)이다.

클라이언트와 주고받은 데이터를 저장해두지 않는 것이다.

 

즉, http프로토콜을 사용하면 금붕어가 되는 것이다.

인간관계로 비교해 봤을때,

계속 그 사람과 함께하지도 못하는데, 그 사람을 기억하지도 못하는 것이다.

 

그래서 이 슬픈 상황을 쿠키를 통해 해결한다.

 

서버는 곧 끊어질 연결을 대비하여 클라이언트에게 응답과 함께 눈물로 젖은 쿠키를 보낸다.

"나... 이제 널 잊게 돼... 그러니까... 다음에 나한테 올때 꼭 이 쿠키를 가지고 와.. 그럼 내가 널 잊지않고 기억할께...."

 

쿠키를 받아든 클라이언트는 축축히 젖은 쿠키를 꼬옥 쥐어들 따름이었다....

시간이 흘러 다시금 서버로 향하는 클라이언트의 손에는 쿠키가 있다.

(이후 브라우저는 쿠키와 함께 서버에 요청)

그리고 쿠키를 본 서버는 말 없이 미소를 지었다.

 

.....(병...)

 

5.1 쿠키

이러한 쿠키는 로그인과 같은 기능을 구현해야 할 때 중요하다.

클라이언트의 신원이 중요한 상황이기 때문이다.

(단순히 사전과 같이 정보제공만 할 서버라면 필요없겠다.)

 

쿠키 : 클라이언트 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일
세션 : 쿠키를 기반으로 하지만 사용자 정보파일을 브라우저가 아닌 서버측에서 관리

 

쿠키는 브라우저에 정보가 남는 방식이라고 볼 수 있다.

서버에 자신을 증명하기 위해 이름과 같은 개인정보가 작성되어 있을 수 있다.

이는 곧 보안에 위협이 된다.

이러한 문제를 해결하기 위해 쿠키의 만료를 지정하는 등 쿠키는 다양한 안전장치를 제공하고 있다.

 

5.2 세션

그럼에도 데이터 자체를 가지고 있다는 쿠키 자체가 가지는 단점을 극복하기 위해

세션이 등장한다.

세션은 데이터를 서버의 DB에 저장하고 데이터에 접근할 수 있는 키를 클라이언트에 전달하는 방식을 취한다.

이를 통해 브라우저에서는 쿠키가 아닌 세션을 이용하고 있다는 점만 알 수 있을 뿐 구체적인 데이터를 알 수 없다.

(+ 브라우저가 종료되는 쿠키와 다르게 세션은 삭제된다.)

 

그렇다면 눈물 젖은 쿠키는 세션에 완전히 대체되는가?

그렇지 않다.

세션은 서버자원을 잡아먹고, 비교적 느리기 때문이다.

보안이 중요한 부분에서 적절하게 세션을 사용할 필요가 있다.

 

5.3 쿠키 사용과 옵션

const http = require("http");

http.createServer((req, res) => {
	//쿠키 읽는 방법, 쿠키 읽기 위해서는 추가 파싱작업 필요
	console.log(req.url, req.headers.cookie);
    //쿠키 전달 방법, 쿠키 전달 위해서는 응답메시지 headers에 작성
    res.writeHead(200, { "Set-Cookie" : "mycookie=test" });
    res.end("Hello Cookie");
})
	.listen(8080, () => {
    	console.log("8080포트에서 서버 대기 중...")
    })

 

위 방법 말고도 찾아본 결과 여러가지 쿠키를 작성하는 방법이 있었다. (res.cookie, res.setHeader, res.writeHead...)

하지만 어차피 http를 이용한 서버제작은 하지 않을 것임에... 깊게 들어가지는 않겠음...

 

Set-Cookie에는 다양한 옵션이 있다.

a. 쿠키명 = 쿠키값

b. Expires = 날짜 : 해당 기한이 되면 만료 (기본값은 클라이언트 종료 지점)

c. Max-age = 초 : 해당 초가 지나면 만료 (Expires보다 우선)

d. Domain = 도메인명 : 쿠키 전송 도메인 특정 (기본값 현재 도메인)

e. Path = URL : 쿠키 전송 URL 특정 (기본값 '/' (모든 URL에 쿠키전송 의미) )

f. Secure : https일 경우에만 쿠키 전송

g. HttpOnly : JS에서 쿠키 접근 불가 (Good Option)

 

6. HTTPS

웹서버에 SSL 암호를 추가하는 모듈이다.

오가는 데이터를 암호화하여 중간에 다른 사람이 요청을 가로채더라도 내용확인이 불가능하다.

(요즘 거의 필수!)

 

사용을 위해서는 SSL/TLS 인증서가 필요하다.

(+ 포트번호 443쓰면 포트번호 생략가능)

 

7. HTTP2

SSL암호화와 더불어 최신 HTTP프로토콜인 HTTP/2를 사용하는 모듈이다. (보안도 챙기고, 속도도 챙기고)

요청 응답 방식이 기존 HTTP/1.1보다 개선되어 웹 속도가 개선되었다. (동시성이 좋아짐)

 

개발은 HTTP로 하고,

실무배포는 HTTP2로 하자!

 

8. cluster

기본적으로 싱글스레드인 노드에서,

CPU코어 모두를 사용할 수 있게 해주는 모듈

 

cluster는 서버에 무리를 덜 가게 해준다. (요청이 분산되어 수행되므로)

cluster를 사용하면 코어 하나당 노드 프로세스 하나를 배정할 수 있다. (일반적으로는 코어 하나만 사용한다.)

cluster를 통해 8개 프로세스를 돌린다고 성능이 8배가 되는 것은 아니다. 개선이 되는 것.

cluster의 단점으로는 컴퓨터 자원(메모리, 세션 등) 공유가 안된다는 점이다. 이는 Redis 등 별도 서버로 해결한다. 

 

 

 

참고❤️

https://www.zerocho.com/book/1

 

ZeroCho Blog

ZeroCho의 Javascript와 Node.js 그리고 Web 이야기

www.zerocho.com

 

https://velog.io/@octo__/%EC%BF%A0%ED%82%A4Cookie-%EC%84%B8%EC%85%98Session

 

쿠키(Cookie) & 세션(Session)

HTTP 프로토콜의 특징 HTTP 프로토콜의 특징은 다음과 같다. Connectionless(비연결지향) HTTP 프로토콜은 클라이언트에서 서버에 요청(Request)을 보내면 서버는 클라이언트에 응답(Response)을 하고 연결을

velog.io

 

'Node.js' 카테고리의 다른 글

3. passport [express]  (1) 2024.12.02
2. express (서버제작 level 2) [express]  (0) 2024.11.11
3. 노드 기본 [Node]  (8) 2024.11.05
4. 패키지 [Node]  (2) 2024.11.04
2. 노드 사용법 [Node]  (0) 2024.11.03