티스토리 뷰
bcypt(비크립트)는 블로피시 암호에 기반을 둔 암호화 해시 함수다.
암호화는 비밀번호를 노출되지 않도록 해시값으로 변경하여 저장을 하는 것인데, 여기서는 회원가입 시 저장하기 전에 변경을 하는데에 bcrypt 라이브러리를 사용한다.
userSchema.pre('save', (next) => {});
userSchema가 호출되는 라우터가 있을 때, 그전에 먼저 pre미들웨어를 실행을 해준다. 그리고 next를 하면 스키마를 호출한 곳으로 돌아간다.
const userSchema = mongoose.Schema(
...
);
userSchema.pre('save', (next) => {
var user = this;
});
여기서 var user = this는 userSchema 자기 자신을 가리킨다.
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const jwt = require('jsonwebtoken');
const userSchema = mongoose.Schema(
...
);
userSchema.pre('save', (next) => {
var user = this;
bcrypt.genSalt(saltRounds, (err, salt) => {
if(err) return next(err)
bcrypt.hash(user.password, salt, (err, has) => {
...
});
});
});
여기서 bcrypt.gensalt에서 에러가 발생하였을 때 스키마를 호출한 곳으로 바로 에러와 함께 넘어간다. salt생성이 제대로 되었을 경우 아래 bcrypt.hash로 넘어간다.
user.password는 사용자가 직접 입력한 비밀번호를 의미한다.
그렇게 완성된 코드는 다음과 같다.
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const jwt = require('jsonwebtoken');
const userSchema = mongoose.Schema(
{
nickname: String,
email: {
type: String,
trim: true,
unique: true,
},
password: String,
role: {
type: Number,
default: 0,
},
token: String,
tokenExp: Number,
},
{ collection: 'users' },
);
userSchema.pre('save', (next) => {
var user = this;
bcrypt.genSalt(saltRounds, (err, salt) => {
if(err) return next(err)
bcrypt.hash(user.password, salt, (err, has) => {
if (err) return next(err);
user.password = hash;
next();
});
});
});
const User = mongoose.model('User', userSchema);
module.exports = { User };
여기까지 했을 경우 유저가 회원가입을 했을 때 비밀번호를 해쉬로 변경해서 저장을 할 수 있도록 해주었다.
하지만 이름, 이메일, 비밀번호를 바꾸는 경우가 종종 있다. 이때 계속 해쉬값을 변경을 하면 안 되고, 비밀번호를 바꿀 때에만 변경을 가능하도록 해주는 기능을 추가하려고 한다.
userSchema.pre('save', (next) => {
var user = this;
if (user.isModified('password')) {
bcrypt.genSalt(saltRounds, (err, salt) => {
if (err) return next(err);
bcrypt.hash(user.password, salt, (err, hash) => {
if (err) return next(err);
user.password = hash;
next();
});
});
}
});
여기서 isModified는 주어진 경로 중 하나라도 수정이 되면 true를 반환을 하고 그렇지 않으면 false를 반환을 해준다. 여기서는 password가 수정이 되었을 때에만 비밀번호 암호화를 실행해준다는 의미를 가진다.
그러면 회원가입 시 비밀번호를 DB에 바로 저장이 되지 않는 것을 알 수 있다.
필자는 실제 테스트 결과 몇가지 오류를 발견했다.
서버에서 isModified는 함수가 아니다 라는 에러를 발견했고 찾아보니까 다음과 같은 내용이 있다.
화살표 함수를 쓰면 this의 범위가 바뀌기 때문에 isModified를 쓸 때는 function으로 사용해야 한다고 한다.
또한 몽구스의 미들웨어를 사용할때에는 this는 쿼리이기 때문에 위 이미지와 같이 해야 한다고 한다.
그래서 필자는 일단 해당 코드만 function으로 변경을 했다.
userSchema.pre('save', function (next) {
var user = this;
if (user.isModified('password')) {
bcrypt.genSalt(saltRounds, 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();
});
});
}
});
공식문서를 찾아보니까. 화살표 함수는 this에 대한 바인딩이 없다.라는 문구가 있다는데...
아직은 이해가 잘 되지 않네요.. 이 부분은 더 찾아봐야 할 듯 하다...
이 부분은 조금 더 후에 다시 찾아보는 걸로...
'Back-End > Node' 카테고리의 다른 글
multerS3를 이용하여 AWS S3 버킷에 이미지 업로드 하기 (0) | 2022.07.23 |
---|---|
node mongodb s3 imageUpload Error (0) | 2022.07.09 |
mongoDB : Databases 이름 변경하기 (0) | 2022.04.16 |
NestJS : NestJS가 무엇인지, 그리고 어떻게 생성을 하는지에 대하여 (0) | 2021.05.22 |
React-Youtube : mongodb 댓글 추가 생성하기 (0) | 2021.05.07 |
- Total
- Today
- Yesterday
- 파이썬
- 리액트 썸네일
- 뷰
- mongodb
- 자바스크립트
- github
- 노드
- 재공부
- node.js
- node
- react
- 코딩테스트
- redux
- 리액트
- Visual Studio Code
- Git
- javascript
- Switch
- 배열
- java
- 프로그래머스
- 함수
- CSS
- 리덕스
- Coding Test
- 리액트 유튜브
- array
- programmers
- node-sass
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |