티스토리 뷰
🌱 [인프런] 따라하며 배우는 노드, 리액트 시리즈 - 기본강의
# boiler-plate 만들기 (#11 ~ #12)
13+. 비밀번호 암호화 관련 User.js 추가사항
비밀번호가 아니라 다른 정보를 바꿀 때는 그냥 next(); 해줘야함.
User.js에서 비밀번호 수정할때 if(user.isModified('password'){...} 하고 else{next();} 까지 해줘야 user.save()로 넘어갈 수 있음. else{next();} 부분을 작성하지 않으면 계속 여기 머물러있음.
// User.js
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()
})
});
} else { // else 부분 추가
next();
}
})
14. 로그인 기능 만들기
로그인 route 생성
// index.js
app.post('/login', (req, res) => {
// 1. 요청된 이메일이 데이터베이스에 있는지 찾기
// 2. 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
// 3. 비밀번호까지 일치한다면 토큰 생성
});
1) findOne 메서드(몽고db메서드)로 데이터베이스에 입력받은 이메일이 있는지 확인해서 없으면
res.json데이터로 loginSuccess를 false로, message와 함께 return
// index.js
app.post('/login', (req, res) => {
// 1. 요청된 이메일이 데이터베이스에 있는지 찾기
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: '입력한 이메일과 일치하는 유저가 없습니다.'
});
}
// 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
});
// 3. 비밀번호도 일치한다면 토큰 생성
});
2) 이메일이 일치하는 유저가 있다면 비밀번호가 맞는지 확인
User모델에 comparePassword라는 메서드를 만들어서 비밀번호 일치여부 확인에 사용
// index.js
app.post('/login', (req, res) => {
// 1. 요청된 이메일이 데이터베이스에 있는지 찾기
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: '입력한 이메일과 일치하는 유저가 없습니다.'
});
}
// 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
user.comparePassword(req.body.password, (err, isMatch) => {
if(!isMatch) {
return res.json({
loginSuccess: false,
message: '비밀번호가 일치하지 않습니다.'
})
}
// 3. 비밀번호도 일치한다면 토큰 생성
});
});
});
입력받은 plainPassword와 db에 저장되있는 암호화된 비밀번호가 일치하는지 확인하려면
plainPassword를 암호화하여 서로 일치하는지 확인해야함 -> bcrypt.compare()
// User.js
userSchema.methods.comparePassword = function(plainPassword, cb) {
bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
if(err) return cb(err); // 일치하지않으면 err
cb(null, isMatch); // 일치하면 err는 없고 isMatch(=true) 전달
});
}
3) 비밀번호까지 일치하면 토큰을 생성해야함 -> 토큰생성을 위해 JSONWEBTOKEN이라는 라이브러리 설치
npm install jsonwebtoken --save
jsonwebtoken 참고: https://www.npmjs.com/package/jsonwebtoken
// User.js
const jwt = require('jsonwebtoken');
.
.
.
userSchema.methods.generateToken = function(cb) {
var user = this; // es5 문법
var token = jwt.sign(user._id.toHexString(), 'secretToken');
user.token = token;
user.save(function(err, user) {
if(err) return cb(err);
cb(null, user); // save가 잘 됬으면 err는 없고 user(유저정보) 전달
});
}
user._id에서 _id는 몽고db에서 생성된 _id부분.
user._id + 'secretToken' 해서 token 생성 -> token 해석할 때 'secretToken'를 넣으면 user._id가 나옴.
user._id.toHexString()은 user._id를 plain Object로 만들기위해 -> 안해주면 오류남
4) 토큰을 쿠키에 저장 (로컬스토리 등등 다른데도 가능. 여기서는 쿠키에 저장하는 방법으로 진행)
cookie-paresr 설치 : npm install cookie-parser --save
// index.js
const cookieParser = require('cookie-parser')
app.use(cookieParser());
.
.
.
app.post('/login', (req, res) => {
// 1. 요청된 이메일이 데이터베이스에 있는지 찾기
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: '입력한 이메일과 일치하는 유저가 없습니다.'
});
}
// 2. 요청된 이메일이 데이터베이스에 있다면 비밀번호가 맞는지 확인
user.comparePassword(req.body.password, (err, isMatch) => {
if(!isMatch) {
return res.json({
loginSuccess: false,
message: '비밀번호가 일치하지 않습니다.'
})
}
// 3. 비밀번호도 일치한다면 토큰 생성
user.generateToken((err, user) => {
if(err) return res.status(400).send(err);
// 토큰을 쿠키에 저장
res.cookie('x_auth', user.token)
.status(200)
.json({
loginSuccess: true,
userId: user._id
});
});
});
});
});
5) POSTMAN으로 확인해보기
post방식으로 http://localhost:5000/login에 email과 password보냈을때 정상적으로 작동하는지 확인
'📚 스터디 인증!' 카테고리의 다른 글
[7/23] 1차 스터디 6일차 (0) | 2022.07.26 |
---|---|
[7/21] 1차 스터디 5일차 (0) | 2022.07.21 |
[7/16] 1차 스터디 3일차 (0) | 2022.07.16 |
[7/14] 1차 스터디 2일차 (0) | 2022.07.14 |
[7/12] 1차 스터디 1일차 (0) | 2022.07.12 |
프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그