3. 쿠키와 세션 이해하기
클라이언트에서 보내는 요청의 단점 → 누가 요청을 보내는지 모름.
로그인 이후 새로고침 후에도 로그아웃이 되지 않는 이유는 클라이언트가 서버에 내가 누군지를 지속적으로 알려주고 있기때문.
내가 누구인지 기억하기 위해서 서버는 요청에 대한 응답을 할 때 쿠키라는것을 같이 보낸다. 쿠키는 유효 기간이 있으며 name=로춘남 과 같은 단순한 '키-값'의 쌍이다.
서버로부터 쿠키가 오면 웹 브라우저는 쿠키를 저장해두었다가 다음에 요청 할 때마다 쿠키를 동봉해서 보낸다. 서버는 요청에 들어있는 쿠키를 읽어서 사용자가 누구인지 파악을 하게 된다.
- 쿠키명-쿠키값 : 기본적인 쿠키의값
- Expires=날짜 : 만료 기한. 이 기한이 지나면 쿠키가 제거.
- Max-age=초 : Expires와 비슷하지만 날짜 대신 초를 입력 할 수 있음.
- Domain=도메인명 : 쿠기가 전송될 도메인을 특정
- Path=URL : 쿠키가 전송될 URL을 특정. 기본값은 '/'. 이 경우에는 모든 URL에서 쿠키전송 가능
- Secure : HTTPS일 경우에만 쿠키 전송
- HttpOnly : 설정 시 자바스크립트에서 쿠키에 접근 할 수 없음.
4. https와 http2
https 모듈은 웹 서버에 SSL암호화를 추가. GET이나 POST 요청을 할 때 오가는 데이터를 암호화해서 중간에 다른 사람이 요청을 가로채더라도 내용을 확인 할 수 없게함.
서버에 암호화를 적용하려면 https 모듈을 사용해야하지만, 이것은 아무나 사용 할 수가 없다. 암호화를 적용하는만큼 그것을 인증해줄 수 있는 기관이 필요해서 경우에 따라 인증서는 인증 기관에서 구입을 해야한다. 인증서를 받는 과정은 생각보다 복잡하고 도메인이 따로 필요하다.
만약 발급받은 인증서가 있다면,
const https = require('https');
const fs = require('fs');
https.createServer({
cert: fs.readFileSync('도메인 인증서 경로'),
key: fs.readFileSync('도메인 비밀키 경로'),
ca: [
fs.readFileSync('상위 인증서 경로'),
fs.readFileSync('상위 인증서 경로'),
],
}, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.write('<h1>Hello Node!</h1>');
res.end('<p>Hello Server!</p>');
})
.listen(443, () => {
console.log('443번 포트에서 서버 대기 중입니다!');
});
이런식으로 처리를 해주면 된다. createServer 메소드가 인수 2개를 받는다는것을 알 수 있고, 두 번쨰 인수는 http 모듈과 같이 서버 로직. 첫 번째 인수는 인증서에 관련된 옵션객체이다. 인증서를 구입하면 pem이나 crt, 또는 key 확장자를 가진 파일들을 제공하며, 이 파일들을 fs.readFileSync 메서드로 읽어 cert, key, ca 옵션에 알맞게 넣어주면된다. 실제 서버에서는 80포트 대신 443 포트를 사용하고 있다.
노드의 http2 모듈은 SSL암호화와 더불어 최신 HTTP 프로토콜인 http/2를 사용 할 수 있게 해준다. http2는 기존 http/1.1 보다 요청 및 응답이 개선되며 훨씬 효율적으로 보내는것이 가능하며! 속도도 빠르다!
const http2 = require('http2');
const fs = require('fs');
http2.createSecureServer({
cert: fs.readFileSync('도메인 인증서 경로'),
key: fs.readFileSync('도메인 비밀키 경로'),
ca: [
fs.readFileSync('상위 인증서 경로'),
fs.readFileSync('상위 인증서 경로'),
],
}, (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.write('<h1>Hello Node!</h1>');
res.end('<p>Hello Server!</p>');
})
.listen(443, () => {
console.log('443번 포트에서 서버 대기 중입니다!');
});
http2를 적용했을 경우 https 모듈과 비슷하다. https 모듈을 https2로, createServer 메서드를 createSecureServer 메서드로 바꿔주기만하면 된다!
Icons made by DinosoftLabs from www.flaticon.com
5. cluster
cluster 모듈은 기본적으로 싱글 프로세스로 동작하는 노드가 CPU코어를 모두 사용할 수 있게 해주는 모듈. 포트를 공유하는 노드 프로세스를 여러개 둘 수 있으므로, 요청이 많이 들어왔을 때 병렬로 실행된 서버의 개수만큼 요청이 분산되게 할 수 있다. → 서버에 무리를 덜 가게 할 수 있음.
노드는 보통 코어를 1개만 사용하지만, cluster 모듈을 설정하여 코어 하나당 노드 프로세스 하나가 돌아가게 할 수도 있다. 성능이 1개일때보다 개선은 되지만 메모리를 공유하지 못한다는 단점과, 세션을 메모리에 저장하는 경우 문제가 될 수 있다. 이럴 경우에는 레디스 등의 서버를 도입하여 해결 할 수 있다.
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`마스터 프로세스 아이디: ${process.pid}`);
// CPU 개수만큼 워커를 생산
for (let i = 0; i < numCPUs; i += 1) {
cluster.fork();
}
// 워커가 종료되었을 때
cluster.on('exit', (worker, code, signal) => {
console.log(`${worker.process.pid}번 워커가 종료되었습니다.`);
console.log('code', code, 'signal', signal);
cluster.fork();
});
} else {
// 워커들이 포트에서 대기
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.write('<h1>Hello Node!</h1>');
res.end('<p>Hello Cluster!</p>');
setTimeout(() => { // 워커 존재를 확인하기 위해 1초마다 강제 종료
process.exit(1);
}, 1000);
}).listen(8086);
console.log(`${process.pid}번 워커 실행`);
}
※ 실무에서는 보통 pm2 등의 모듈로 cluster 기능을 사용함.
참조 : Node.js 교과서(개정2판)
'node.js' 카테고리의 다른 글
[Node.js] #6 익스프레스 웹 서버 만들기 (0) | 2021.11.15 |
---|---|
[Node.js] #5 패키지매니저 (0) | 2021.11.15 |
[Node.js] #3 http 모듈로 서버 만들기(1) (0) | 2021.11.12 |
[Node.js] #2노드의 기능 (1) | 2021.11.11 |
[Node.js] #1 node.js 첫 시작. 노드(node.js) 란? (1) | 2021.11.11 |