괴발개발/node.js

[node.js] ch15. AWS와 GCP로 배포하기

ebulsok 2023. 2. 14. 17:04

morgan: 요청과 응답에 대한 정보를 콘솔에 기록

개발환경: app.use(morgan('dev'));

배포환경: app.use(morgan('combined'));

 

시퀄라이즈 배포환경 설정

config.json → config.js

require('dotenv').config();

module.exports = {
    ...
}

 

cross-env: 동적으로 process.env를 변경할 수 있음

// package.json
// ONLY linux/mac
"start": "NODE_ENV=production PORT=80 node server",
"dev": "nodemon server",

// ONLY window
"start": "cross-env NODE_ENV=production PORT=80 node server",
"dev": "nodemon server",

 

sanitize-html, csurf: 공격을 막기 위한 패키지

XSS(cross site scripting): 악의적인 사용자가 사이트에 스크립트를 삽입하는 공격

사용자가 업로드한 html을 함수로 감싸면 허용하지 않는 태그나 스크립트는 제거됨

const sanitizeHtml = require('sanitize-html');

const html = "location.href = '<<a href=https://naver.com>https://naver.com</a>>'" console.log(sanitizeHtml(html))

CSRF(cross site request forgery): 사용자가 의도치 않게 공격자가 의도한 행동을 하게 만드는 공격

CSRF 토큰을 발급

const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

app.get('/form', csrfProtection, (req, res) => {
    res.render('csrf', { csrfToken: req.csrfToken() });
});
app.post('/form', csrfProtection, (req, res) => {
    res.send('ok');
})

 

pm2: 서버 운영을 위한 패키지

멀티 스레딩은 아니지만 멀티 프로세싱을 지원하여 노드 프로세스 개수를 1개 이상으로 늘릴 수 있음. 기본적으로 CPU 코어를 하나만 사용하는데, pm2를 사용해서 프로세스를 여러 개 만들면 다른 코어들까지 사용할 수 있음. 클라이언트로부터 요청이 올 때 알아서 요청을 여러 노드 프로세스에 고르게 분재하므로 하나의 프로세스가 받는 부하가 적어짐

멀티 스레딩이 아니므로 서버의 메모리 같은 자원을 공유하지는 못함 → 멤캐시드/레디스

// package.json
"start": "cross-env NODE_ENV=production PORT=80 pm2 start server.js",
"dev": "nodemon server",

pm2가 노드 프로세스를 백그라운드로 돌리므로 node 명령어와는 다르게 노드 프로세스가 실행된 후에 콘솔에 다른 명령어를 입력할 수 있음

 

npx pm2 list : 백그라운드에서 돌고 있는 노드 프로세스 확인

pid: 프로세스 아이디

uptime과 status 사이: 재시작된 횟수 → npx pm2 logs / npx pm2 logs -err

npx pm2 kill : 프로세스 종료

npx pm2 reload all: 서버 재시작

 

winston: 실제 서버를 운영할 때 console.log/console.error 를 대체하기 위한 모듈

const { createLogger, format, transports } = require('winston');

const logger = createLogger({
    level: 'info',
    format: format.json(),
    transports: [
        new transports.File({ filename: 'combined.log'}),
        new transports.File({ filename: 'error.log', level: 'error' }),
    ],
});

if(process.env.NODE_ENV !== 'production') {
    logger.add(new transports.Console({ format: format.simple() }));
}

module.exports = logger

// app.js
logger.info('hello');
logger.error(error.message);

level: 로그의 심각도. error, warn, info, verbose, debug, silly

format: 로그의 형식. json, label, timestamps, printf, simple, combine

transport: 로그 저장 방식. File, Console

 

helmet, hpp: 서버의 각종 취약점을 보완해주는 패키지

app.use(helmet({ contentSecurityPolicy: false }));
app.use(hpp());

 

connect-redis: 멀티 프로세스 간 세션 공유를 위해 레디스와 익스프레스를 연결해주는 패키지

서버가 종료되어 메모리가 날아가면 접속자들의 로그인이 풀리기 때문에 이를 위해 세션 아이디와 실제 사용자 정보를 데이터베이스(레디스)에 저장

npm i redis connect-redis

redislabs: 레디스를 호스팅해주는 서비스