티스토리 뷰
dotenv
node.js 에서는 dotenv 패키지를 통해 환경변수 파일을 외부에 만들고 관리할 수 있다.
깃허브 등에 오픈소스로 프로젝트를 공개할 때
DB 계정 정보를 소스코드 내에 하드코딩하지 않고 외부 환경변수 파일에 작성하고 .gitignore 을 통해 제외하면 안전하다.
1. Install
npm install --save dotenv
2. Usage
프로젝트 루트경로에 .env 파일을 생성하고 다음과 같이 작성한다.
SERVER_PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=password
단순하게, 변수명=값 형태를 가지고 있다.
프로젝트 상단에 아래 코드를 적어 환경 변수를 불러온다.
require('dotenv').config();
불러온 환경변수는 아래와 같이 사용할 수 있다.
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD
}); //DB 연결 예제 코드
app.listen(process.env.SERVER_PORT, () => {
console.log('sample server is listening to port ' + process.env.SERVER_PORT);
}); //서버 포트 예제 코드
위와 같이 process.env 키워드를 사용하여, 미리 정의한 환경변수에 접근한다.
node.js 비밀 설정 정보(secrets) 관리
외부에 알려지면 않되는 민감한 정보들을 관리하는 방법
세션 키
데이터베이스 접속을 위한 정보 (host, user, password…)
1. 하드 코딩
코드 내에 민감한 정보들을 코딩해놓은 것
mysql 연동 모듈 예제
// https://github.com/mysqljs/mysql#introduction
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
connection.end();
하드코딩하면 안 되는 이유
① 설정 정보가 변경되면 코드를 수정과 배포를 다시 해야 한다.
관심사의 분리(Separation of Concerns)원칙을 적용하여 설정 정보와 코드는 분리되어야 한다.
② github과 같은 SCM(source code management)를 사용하는 경우, 비밀 정보가 노출되므로 별도의 행위가 필요하다.
2. 설정파일 사용하기
설정 정보를 JSON file에 저장해 두고 require()를 사용하여 필요 정보를 get 하는 예제
var mysql = require('mysql');
var db_config = require('./config/db-config.json');
var connection = mysql.createConnection({
host : db_config.host,
user : db_config.user,
password : db_config.password,
database : db_config.database
});
{
"host": "localhost",
"user": "me",
"password": "secret",
"database": "my_db"
}
코드 내에 하드 코딩하는 경우의 단점 중 관심사의 분리 문제는 해결되었다.
하지만 설정 정보가 코드에서 분리되었을 뿐이므로 SCM을 이용한 배포시에 주의해야 한다.
.gitignore file에 설정 파일(db-config.json)을 추가하여 SCM에 저장하지 않는다.
대신 db-config-sample.json과 같은 예제 파일을 등록하고 사용법을 명시한다.
그러나 설정 파일 내부에 비밀 정보가 존재하는 것은 여전히 문제로 남아있고
SCM 배포 시 특정 파일의 배포를 회피해야 하는 번거로움은 그대로이다.
3. command-line에서 argument 요구하기
비밀 정보를 보호하는 가장 좋은 방법은 설정 파일에 저장하지 않는 것이다.
nopt package를 사용하여 command-line에서 설정 정보를 argument로 요구하면 비밀 정보는 파일로 존재하지 않아도 된다.
nopt package를 사용하여 argument로 세션 키를 요구하는 예제
// secret-arg.js
var nopt = require("nopt")
var longOpts = {
"sessionSecret": String,
}
var shortOpts = {
"s": ["--sessionSecret"],
}
var parsed = nopt(longOpts, shortOpts, process.argv, 2)
console.log("session secret is:", parsed.sessionSecret)
node secret-arg.js --sessionSecret "keyboard cat"
node secret-arg.js -s "keyboard cat"
설정 정보를 하드코딩하거나 설정 파일로 가지고 있는 것보다 비밀정보 노출에 보다 안전해졌다.
그러나 앱을 실행할 때마다 입력해야 할 정보의 양이 많아진 것은 번거로울 수 있다.
4. 환경변수(environment variable) 사용하기
OSX, Linux에서 환경변수를 설정할 때는 export를 사용하면 된다. 예를 들어 SESSION_SECRET key에 값을 설정해 보자
export SESSION_SECRET="keyboard cat"
Windows에서는 set을 사용하면 된다.
set SESSION_SECRET="keyboard cat"
실행할 때마다 환경변수를 설정할 수도 있다.
SESSION_SECRET="keyboard cat" node secret-env.js
코드 내에서 환경변수에 접근할 때에는 node.js의 process.env를 사용한다.
// https://github.com/expressjs/session 참고
var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({secret: process.env.SESSION_SECRET}))
앞에서 살펴본 command-line에서 argument 요구하기와 비교하면 nopt 패키지를 별도로 사용하지 않아도 된다는 점과
매번 설정 정보를 입력하지 않아도 된다는 것은 좀 더 개선된 방법으로 보인다.
참고사이트
https://poiemaweb.com/nodejs-keeping-secrets
'do > nodejs' 카테고리의 다른 글
express login (0) | 2019.04.09 |
---|---|
Redis (0) | 2019.04.08 |
Request, Response (0) | 2019.04.07 |
Swagger (1) | 2019.04.05 |