클라이언트와 서버 어느쪽이든 개발을 진행할 때 노출되어선 안되는 데이터가 있기에 이러한 민감한 데이터를 관리하는 방법
const mongoose = require("mongoose");
mongoose
.connect(
"복사한 url과 id/password"
)
.then(() => console.log("MongoDB 연결 성공..."))
.catch((err) => console.log(err));
위 코드에 "복사한 url과 id/password"
는 노출되어서는 안되는 데이터입니다.
서버 사이드에서 이러한 데이터는 보통 config 폴더를
생성해서 .gitignore
에 추가해서 관리합니다.
이때 개발 환경을 두가지 경우로 생각해야합니다
따라서 개발 환경과 배포 후의 환경에 따라 값을 가져오는 분기 처리를 해줘야합니다.
위 코드를 예시로 들자면
module.exports = {
mongoURI: "url + id/password"
}
dev는 development의 약자로 개발 환경을 의미합니다.
module.exports = {
mongoURI: process.env.MONGO_URI
}
prod는 production의 약자로 배포 후의 환경을 의미합니다.
process.env.NODE_ENV === 'production'
? module.exports = require('./prod')
: module.exports = require('./dev');
process.env.NODE_ENV는 환경 변수로 로컬 환경에서는 development, 배포 후의 환경에서는 production이 나오기 때문에 위와 같이 분기 처리를 해줄 수 있습니다.
const mongoose = require("mongoose");
const config = require("./config/key");
mongoose
.connect(config.mongoURI)
.then(() => console.log("MongoDB 연결 성공..."))
.catch((err) => console.log(err));
dev.js
추가
이제 위 코드와 같이 로컬/배포 각 환경에서 환경 변수에 따라 분기 처리를 해줄 수 있고 .gitignore를 이용해서 민감한 데이터를 노출시키지 않을 수 있습니다.
깃헙에 push해서 레포에 dev.js가 올라가지 않느지 확인
위 그림에서 받은 데이터의 password는 암호화가 되어있지 않기 때문에 관리자등에게 비밀번호가 노출될 수 있어 password 암호화가 필요합니다.
bcrypt
데이터를 암호화 할 수 있도록 도와주는 모듈
app.post("/api/users/register", (req, res) => {
const user = new User(req.body);
user.save( ... );
});
위 코드에서 확인해보면 req.body로 받은 데이터를 save()하고 있습니다.
따라서 데이터를 받기 전에 암호화를 한다면 암호화된 데이터를 넘겨 받을 수 있습니다.
이 기능은 mongoose의 기능과 bcrypt 모듈을 함께 사용하여 만들 수 있습니다.
const userSchema = mongoose.Schema({ ... });
userSchema.pre('save', function(next) {
// 비밀번호 암호화 과정
...something...
next();
});
위 코드는 유저 모델에 데이터를 save() 전에 ...something... 과정을 거치고 next()를 통해 save()로 넘어간다는 의미입니다.
이제 위의 ...something... 과정안에 bcrypt 모듈을 사용해서 암호화를 진행합니다.
bcryptjs
npm i bcrypt
const bcrypt = require("bcrypt");
userSchema.pre("save", function (next) {
var user = this;
// 비밀번호 암호화 과정
if (user.isModified("password")) {
bcrypt.genSalt(10, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
} else {
next();
}
});
if (user.isModified("password")) { ... } else { next() }
유저의 비밀번호가 변경되었을 때만 아래 과정을 수행하고 아닐 경우 next()로 빠져나가 일반적인 save()를 하게됩니다.
bcrypt.genSalt(saltRounds, function (err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function (err, hash) {
// Store hash in your password DB.
});
})
문서에 나와있는 사용법으로 salt와 hash를 생성하고 myPlaintextPassword(암호화 전의 password 값)을 가져오기 위해 this를 사용하고 에러처리를 하고 성공한다면 생성된 암호화된 비밀번호(hash)를 유저의 비밀번호로 교체합니다.
Postman과 MongoDB에 암호화된 비밀번호가 저장되는지 확인
Postman | Postman |
---|---|
MongoDB |
---|