저번 몽고디비 사용법 3에 이어서 알아보겠습니다.
목표
- 암호화 과정
- 몽구스 스키마의 virtual 메소드
- 비밀번호 암호화하여 저장
암호화 과정
데이터베이스를 암호화 하여 저장하기 위해선 다음과 같은 절차가 필요합니다.
1. 사용자로부터 비밀번호를 받음
2. 암호화를 위한 salt 값을 생성함
3. 비밀번호를 암호화 함
4. 암호화한 비밀번호와 salt 값을 저장
암호화하기전 비밀번호를 받기위해 virtual 메소드를 사용합니다. 이를 사용하면 스키마에 가상으로 속성을 설정하여 값을 받을 수 있습니다. 그리고 virtual 메소드 내에서 받은 값을 암호화하여 데이터베이스에 저장할 수 있습니다.
salt 값은 암호화를 위한 key입니다. 같은 비밀번호, 같은 salt를 encryptPassword 메소드에 입력하면 동일한 값을 반환합니다. 로그인할 때를 위해 이 salt값도 암호화된 비밀번호와 함께 저장합니다.
몽구스 스키마의 virtual 메소드
몽고디비 사용법 3에서 스키마에 static 메소드를 추가한 것과 같이 virtual 메소드를 추가할 수 있습니다.
다음은 id와 name 속성을 갖는 UserSchema에 info라는 가상 속성을 설정해 id와 name 속성을 저장하는 예제입니다.
UserSchema = mongoose.Schema({
id : String,
name : String
});
UserSchema
.virtual('info')
.set(function(info){
var splitted = info.split(' ');
this.id = splitted[0];
this.name = splitted[1];
})
.get(function(){ return this.id + ' ' + this.name});
...
var user = new UserModel({'info': 'jjang01 짱구'});
user.save();
해당 예제는 다음과 같이 id와 name 속성을 통해 user를 저장하는 것과 동일하게 작동합니다.
var user = new UserModel({'id': 'jjang01', 'name': '짱구'});
user.save();
get은 user.info를 호출 했을 때 반환하는 값을 설정합니다.
console.log(user.info) // 'jjang01 짱구' 출력
console.log(user.name + ' ' + user.id) // 'jjang01 짱구' 출력
비밀번호를 암호화하여 저장
먼저 % npm install crypto --save 명령어로 암호화를 위한 encrypt 모듈을 설치합니다.
다음과 같이 스키마와 스키마 객체의 메소드를 정의합니다.
UserSchema = mongoose.Schema({
id: {type: String, required: true, unique: true},
hashed_password : {type: String, required: true, 'default': ' '},
salt : {type: String, required: true},
});
// password 를 virtual 메소드로 정의 : 몽고디비에 저장되지 않는 편리한 속성. 특정 속성을 지정하고 set, get 메소드를 정의
UserSchema
.virtual('password')
.set(function(password){
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
console.log('virtual password 호출됨 : ' + this.hashed_password);
})
.get(function(){return this._password});
// 비밀번호 암호화 메소드
UserSchema.method('encryptPassword', function(plainText, inSalt){
if(inSalt){
return crypto.createHmac('sha1', inSalt).update(plainText).digest('hex');
} else{
return crypto.createHmac('sha1', this.salt).update(plainText).digest('hex');
}
});
// salt 값 만들기 메소드
UserSchema.method('makeSalt', function(){
return Math.round((new Date().valueOf() * Math.random())) + '';
});
// 인증 메소드 - 입력된 비밀번호와 비교 (true/false 리턴)
UserSchema.method('authenticate', function(plainText, inSalt, hashed_password){
if(inSalt){
console.log('authenticate 호출됨 : %s -> %s : %s', plainText,
this.encryptPassword(plainText, inSalt), hashed_password);
return this.encryptPassword(plainText, inSalt) === hashed_password;
} else{
console.log('authenticate 호출됨 : %s -> %s : %s', plainText,
this.encryptPassword(plainText), hashed_password);
return this.encryptPassword(plainText) == hashed_password;
}
});
'Do it! Node.js 프로그래밍'을 공부한 내용입니다.
'개발 > Node.js' 카테고리의 다른 글
[Node.js] 뷰 템플릿 적용하기 - ejs 뷰 (2) | 2021.01.11 |
---|---|
[Node.js] windows에서 노드 버전 변경 - downgrade/upgrade (1) | 2021.01.11 |
[Node.js] 익스프레스에서 몽고디비 사용법 3 - 몽구스로 DB 다루기 (0) | 2021.01.07 |
[Node.js] 익스프레스에서 몽고디비 사용법 2 - 문서 추가와 조회 (0) | 2021.01.05 |
[Node.js] 익스프레스에서 몽고디비 사용법 1 - 데이터베이스 연결 (0) | 2021.01.04 |
댓글