본문 바로가기

clone toy projects/node_express_sns

서비스 운영을 위한 패키지[morgan,express-session,시퀄라이즈,cross-env, sanitize-html, csurf]

지금까지는 서버 개발을 localhost에서 진행했습니다.

별다른 설정 없이 서버 작업 결과를 볼 수 있어 편리하긴 하지만, 혼자만 볼 수 있다는 문제가 있습니다.

 

배포시에는 다른 사람이 사용하는 서비스이므로 개발 환경과 동일하게 진행할 수는 없습니다.

서버도 멈추지 않게 유지해야 하고, 에러 내역도 관리해야 합니다. 또한, 각종 보안 위협에도 대처해야 합니다.

이러한 작업을 쉽게 해주는 패키지도 알아볼 것입니다.

 

morgan과 express-session

현재 익스프레스 미들웨어 중 일부가 개발용으로 설정되어 있습니다. 이 미들웨어들을 배포용으로 설정할 것입니다.

process.env.NODE_ENV는 배포 환경인지 개발 환경인지를 판단할 수 있는 환경 변수입니다.

저는 주로 배포 환경일 때는 morgan을 combined 모드로 사용하고, 개발 환경일 때는 dev 모드로 사용합니다. 

combined 모드는 dev 모드에 비해 더 많은 사용자 정보를 로그로 남기므로 추후 버그를 해결할 때 더 유용하게 사용할 수 있습니다.

 

참고로 process.env.NODE_ENV는 .env에 넣을 수 없습니다. 개발 환경인지 배포 환경인지에 따라 값이 변해야 하는데, .

env 파일은 정적 파일이기 때문입니다. NODE_ENV를 동적으로 바꾸는 방법은 cross-env에서 알아봅니다.

이번에는 express-session을 배포용으로 설정합니다.

단, express-session은 사용자의 환경에 따라 설정이 달라지므로 설명을 주의 깊게 읽어주세요.

 

배포 환경일 때는 proxy cookie.secure true로 바꿉니다.

지만 무조건 이렇게 적용해야 하는 것은 아닙니다. 

proxy true로 적용해야 하는 경우는 https 적용을 위해 노드 서버 앞에 다른 서버를 뒀을 때입니다. 

cookie.secure도 https를 적용할 때만 true로 바꿉니다.

 

 

시퀄라이즈

데이터베이스도 배포 환경으로 설정합니다. 시퀄라이즈(sequelize)의 경우 수정이 필요합니다.

시퀄라이즈에서 가장 큰 문제는 비밀번호가 하드 코딩되어 있다는 것이며, JSON 파일이므로 변수를 사용할 수 없습니다.

다행히 시퀄라이즈는 JSON 대신 JS 파일을 설정 파일로 쓸 수 있게 지원합니다.

config 폴더에서 config.json을 지우고 config.js를 생성하고 그대로 옮깁니다.

 

 

JS 파일이므로 dotenv 모듈을 사용할 수 있습니다.

예제에서는 password process.env로 바꿨지만, 보안 규칙에 따라 나머지 정보도 process.env로 바꿔도 됩니다.

특히 username 속성이나 host 속성은 각각 아이디와 DB 서버 주소 역할을 하므로 숨기는 게 좋습니다.

 

process.env development일 때는 development 속성의 설정 내용이 적용되고, 

production일 때는 production 속성의 설정 내용이 적용됩니다.

실무에서는 개발용 데이터베이스와 배포용 데이터베이스를 구별하기도 하므로 이렇게 구분하는 것이 유용합니다.

11장에서는 테스트용 데이터베이스를 구별했습니다.

지금은 쿼리를 수행할 때마다 콘솔에 SQL문이 노출됩니다.

배포 환경에서는 어떤 쿼리가 수행되는지 숨기는 것이 좋습니다.

따라서 production일 경우에는 logging false를 줘서 쿼리 명령어를 숨겼습니다.

데이터베이스 비밀번호는 .env 파일에 입력합니다.

 

 

cross-env

cross-env 패키지를 사용하면 동적으로 process.env(환경 변수)를 변경할 수 있습니다.

또한, 모든 운영체제에서 동일한 방법으로 환경 변수를 변경할 수 있게 됩니다.

기존 package.json을 다음과 같이 바꿉니다.

서버 실행을 위한 npm 스크립트를 두 개로 나눴습니다. 

npm start 배포 환경에서 사용하는 스크립트이고, npm run dev개발 환경에서 사용하는 스크립트입니다. 

npm start 시에 실행되는 명령어가 좀 독특한데, 앞에 NODE_ENV=production PORT=80이 붙어 있습니다.

스크립트를 실행할 때 process.env를 동적으로 설정하는 방법입니다. 

process.env.NODE_ENV production이 되고, process.env.PORT 80이 됩니다.

 

sanitize-html, csurf

sanitize-htmlcsurf 패키지

각각 XSS(Cross Site Scripting), CSRF(Cross Site Request Forgery) 공격을 막기 위한 패키지입니다.

npm i sanitize-html
npm i csurf

XSS악의적인 사용자가 사이트에 스크립트를 삽입하는 공격입니다.

악성 사용자가 게시글이나 댓글 등을 업로드할 때 자바스크립트가 포함된 태그를 올리면,

나중에 다른 사용자가 그 게시글이나 댓글을 볼 때 해당 스크립트가 실행되어 예기치 못한 동작을 하게 됩니다.

따라서 서버에서는 사용자가 게시글을 업로드할 때 스크립트가 포함되어 있는지 검사해서, 존재한다면 제거해야 합니다.

다만, 공격성 스크립트의 유형이 많으므로 라이브러리의 도움을 받는 것이 좋습니다.

사용법은 간단합니다.

사용자가 업로드한 HTML sanitize-html 함수로 감싸면 허용하지 않는 태그나 스크립트는 제거됩니다.

두 번째 인수허용할 부분에 대한 옵션을 넣을 수 있는데, 옵션 목록은 공식 문서를 참고하면 됩니다.

 

CSRF는 사용자가 의도치 않게 공격자가 의도한 행동을 하게 만드는 공격입니다.

예를 들어, 특정 페이지에 방문할 때 저절로 로그아웃되거나 게시글이 써지는 현상을 유도할 수 있습니다.

심지어 은행과 같은 사이트에서는 다른 사람에게 송금하는 행동을 넣는 등 상황에 따라 크게 악용될 수 있는 공격입니다.

공격을 막으려면 내가 한 행동이 내가 한 것이 맞다는 사실을 인증해야 합니다.

이때 CSRF 토큰이 사용되고, csurf 패키지는 이 토큰을 쉽게 발급하거나 검증할 수 있도록 돕습니다.

다음 코드는 공식 문서에서 발췌한 예제입니다. 

GET /form 라우터 form을 렌더링하는 라우터이고, 

POST /form 라우터는 form에서 보낸 데이터를 처리하는 라우터입니다.

익스프레스의 미들웨어 형식으로 동작하며 form 같은 것을 렌더링할 때 CSRF 토큰을 같이 제공합니다.

현재 cookie를 사용하는 것으로 옵션을 설정했으므로 cookie-parser 패키지도 연결되어 있어야 합니다.

큰은 req.csrfToken()으로 가져올 수 있습니다.

프런트엔드에 렌더링된 CSRF 토큰을 나중에 form을 제출할 때 데이터와 함께 제출하면 됩니다.

상황에 따라 CSRF 토큰을 적용하는 방법이 다른데, 이는 공식 문서를 참고하면 됩니다.