암호화하는 이유
지난시간 POSTMAN을 통해 개인정보 전송함
mongoDB > databases > browse collection > query results
_id : ObjectId("61f7934f1bccc54aa85990d8") name : "james123" email : "james@naver.com" password : "123123" role : 0 __v :0
정보 등록되어있지만 보안에 취약
-> 암호화해서 데이터베이스에 저장
순서
1) 다운로드
bycrypt 라이브러리 다운로드
npm install bcrypt --save
2) register router 부분에서 암호화
생성된 salt로 비밀번호 암호화
a) salt 생성 (코드 붙여넣기)
b) salt Rounds (salt가 몇글자인지, default 10)
User.js
const bcrypt = require('bcrypt') const saltRounds = 10; userSchema.pre('save', function(next) { //비밀번호 암호화 var user = this; if(user.isModified('password')) { // pw변경시에만 해쉬값 넣도록 bcrypt.genSalt(saltRounds, function(err, salt) { if(err) return next(err) //에러나오면 index로 bcrypt.hash(user.password, salt, function(err, hash) { // Store hash in your password DB. if(err) return next(err) user.password = hash next() // hash값 저장했으면 index로 }); }); } else { next() } })
_id : ObjectId("61fb89f50d659a386d8c72f6") name : "james3434" email : "jamedds@naver.com" password : "$2b$10$9ZGYzAkMClob8UZ3ivcZHObj7a9skF6DIgmU1s7Ml28LLd7LQG0l." role : 0 __v : 0
로그인 route
a) 요청된 이메일을 데이터베이스에 있는지 찾기
b) 요청한 이메일이 데이터베이스에 있다면 비밀번호 맞는지 확인
c) 토큰 생성하기 (jsonwebtoken 이용)
npm install jsonwebtoken --save npm install cookie-parser --save
index.js
const cookieParser = require('cookie-parser') app.use(cookieParser()); -------------------------------------------------------------------------------------------- app.post('/login',(req,res) => { // 요청된 이메일을 데이터베이스에 있는지 찾기 User.findOne({email: req.body.email}, (err, user) => { if(!user) { return res.json({ loginSuccess: false, message: "제공된 이메일에 해당하는 유저가 없습니다." }) } // 요청한 이메일이 데이터베이스에 있다면 비밀번호 맞는지 확인 user.comparePassword(req.body.password, (err, isMatch) => { if(!isMatch) return res.json({loginSuccess: false, message: "비밀번호가 틀렸습니다."}) // 토큰 생성하기 user.generateToken((err, user) => { //jsonwebtoken 활용 if(err) return res.status(400).send(err); // 토큰을 저장한다. 어디에? -> 여러곳 가능 [쿠키, 세션, 로컬스토리지] // 어디가 가장 안전한지는 사람마다 다름, 로컬, 쿠키 등등 // 여기서는 쿠키 -> 라이브러리 다운로드 필요 (express에서 제공하는 cookie paraser) res.cookie("x_auth", user.token) .status(200) .json({ loginSuccess: true, userId: user._id }) }) }) }) })
User.js
const bcrypt = require('bcrypt'); const saltRounds = 10; const jwt = require('jsonwebtoken'); ---------------------------------------------------------------------------------------- userSchema.methods.comparePassword = function(plainPassword, cb) { // plainPassword 1234567 일 때 암호화된 비밀번호(해쉬값) 비교 bcrypt.compare(plainPassword, this.password, function(err, isMatch) { if(err) return cb(err), cb(null, isMatch) }) } ----------------------------------------------------------------------------------------- userSchema.methods.generateToken = function(cb) { var user = this; // ES5문법 //jsonwebtoken이용해서 token생성 var token = jwt.sign(user._id.toHexString(), 'secretToken') //user._id + 'secretToken' = token //_id는 데이터베이스에 저장된 id값 // -> 'secretToken' -> user_.id 확인가능 user.token = token user.save(function(err, user) { if(err) return cb(err) cb(null, user) }) }