오늘은 지난 시간에 해싱에 대해서 공부했는데 그 개념을 가지고 입력받은 사용자에 비밀번호를 암호화하는 방법에 대해서 공부해 보겠습니다.!!
클라이언트가 서비스에 가입 시 이메일과 비밀번호를 입력하여 서버에 전달하였습니다.
서버에서 데이터베이스에 사용자에 비밀번호를 저장할때 평문 비밀번호로 저장하면 디비에 접근할 수 있는 사람들이 비밀번호를 볼 수 있고 해커가 DB를 공격하면 다 털리는 건 일도 아니겠죠?
문제가 있는 평문으로 저장되는 비밀번호
몽고DB에 위에 사용자에 요청받은 email과 password를 저장했습니다.
비밀번호는 암호화를 해야겠죠?
bcrypt js 모듈 설치
$ npm install bcryptjs
bcryptjs 모듈 불러오기
const bcrypt = require('bcryptjs');
bcryptjs를 사용하여 비밀번호 암호화 프로세스
1. 클라이언트는 모든 정보를 입력 후 등록하기 버튼을 클릭하면, 서버에서는 http://localhost:3000/api/v1/auth/register 엔드포인트를 찾습니다.
2. /register에 대한 핸들러가 실행됩니다.
3. 클라이언트에 정보를 DB에 저장하기 전에 pre('save')함수가 실행되어 클라이언트가 평문으로 입력한 비밀번호를 해싱하여 저장합니다.
4. 그 후에 클라이언트에 정보를 저장합니다.
회원 등록 로직 - controllers/auth.js
1. 클라인언트가 회원가입을 위해 정보를 입력하면 라우터를 통해 http://localhost:3000/api/v1/auth/register에 대한 경로로 들어옵니다.
2. 실행할 Controller에 로직은 다음과 같습니다.
const { BadReqeustError } = require('../errors');
const User = require('../models/User');
const registerUser = async (req, res) => {
const { gender, name, email, password } = req.body;
if (!email || !password) {
throw new BadReqeustError("please provide all information");
}
await User.create(req.body);
}
몽고DB에 create() 전에 실행될 로직
pre('save')함수로 회원을 DB에 저장하기 전에 입력받은 사용자에 평문 비밀번호를 암호하하는 로직을 실행시켜야합니다.
DB에 등록 전에 해당 함수는 무조건 호출이 되게 됩니다.
따라서 비밀번호 변경 시에만 호출이 되도록 조건을 넣어주었습니다.
salt에 자리수를 설정한 후, 현재 비밀번호와 salt를 해시한 값을 현재 비밀번호에 대입합니다.
UserSchema.pre('save', async function() {
if (!this.isModified('password')) {
return;
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
});