Web/Basic (Back-end)

[#7] Bcrypt๋ฅผ ์ด์šฉํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” / ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๐Ÿ“’Bcrypt๋ž€?

bcrypt - npm

> ๋ณด๋‚ผ ๋•Œ๋Š” ์ •๋ณด ๊ทธ๋Œ€๋กœ ๋ณด๋‚ด์ง€๋งŒ ์•”ํ˜ธํ™”ํ•ด์„œ DB์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ.

> Register Route์—์„œ, ์œ ์ € ์ •๋ณด๋“ค(Account, Password ๋“ฑ)์„ DB์— ์ €์žฅํ•˜๊ธฐ ์ „!์ด ์•”ํ˜ธํ™”ํ•  ํƒ€์ด๋ฐ.

> Bcrypt๋ฅผ ์ด์šฉํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”ํ•˜๋ ค๋ฉด salt๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•จ.

 

๐Ÿ“’๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

  1. DB์—์„œ ์š”์ฒญํ•œ E-mail ์ฐพ๊ธฐ
  2. DB์—์„œ ์š”์ฒญํ•œ E-mail์ด ์žˆ๋‹ค๋ฉด ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์€์ง€ ํ™•์ธ
  3. ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™๋‹ค๋ฉด Token ์ƒ์„ฑ
  4. ์ƒ์„ฑํ•œ Token์„ Cookie์— ์ €์žฅ
    (*Token์€ Cookie, Local Storage, Session Storage ๋“ฑ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ณต๊ฐ„์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ฐ๊ฐ ์žฅ๋‹จ์ ์ด ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” Cookie์— ์ €์žฅ)

 

//index.js

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: "๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ‹€๋ฆผ." })

            //๋น„๋ฐ€๋ฒˆํ˜ธ๊นŒ์ง€ ๋งž๋‹ค๋ฉด Token ์ƒ์„ฑ
            //index.js์—์„œ User์— ๋„ฃ์–ด์ค€ ๊ฒƒ์ด user๋กœ ๋“ค์–ด์˜ด.
            user.generateToken((err, user)=>{
                if(err) return res.status(400).send(err); //status(400) : err์žˆ๋‹ค!->send!

                //Token์„ Cookie์— ์ €์žฅ (cookie-parser ์ด์šฉ)
                res.cookie("x_auth", user.token)
                    .status(200)
                    .json({ loginSuccess: true, userId: user._id})
            })
        })
    })
})

 

๐Ÿ“’Token ์ƒ์„ฑ with jsonwebtoken

* ์ฐธ๊ณ : jsonwebtoken - npm

//User.js

userSchema.methods.comparePassword = function(plainPassword, cb){
    bcrypt.compare(plainPassword, this.password, function(err, isMatch){
        if(err) return cb(err);
        cb(null, isMatch)
    })
}
userSchema.methods.generateToken = function(cb){
    //jsonwebtoken์„ ์ด์šฉํ•ด token ์ƒ์„ฑํ•˜๊ธฐ
    var user=this;
    var token=jwt.sign(user._id.toHexString(), 'secretToken') //_id: mongoDB์˜ user collenction์˜ id
    //user._id + 'secretToken' = token ์ด๋ฏ€๋กœ 'secretToken'์„ ๋„ฃ์œผ๋ฉด user._id๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ

    //์ƒ์„ฑํ•œ Token์„ User์— ๋„ฃ์–ด์คŒ.
    user.token=token
    user.save(function(err, user){
        if(err) return cb(err)
        cb(null, user)
    })
}

* 'secretToken'์€ ์ž„์˜์˜ ๋ฌธ์ž์—ด

 

๐Ÿ“’์˜ค๋ฅ˜ํ•ด๊ฒฐ

  • ์˜ค๋ฅ˜๋ฉ”์„ธ์ง€
'Expected "payload" to be a plain object.' 

Token ์ƒ์„ฑํ•  ๋•Œ user._id๊ฐ€ plain object๋กœ ๋“ค์–ด์™€์•ผ ํ•˜๋Š”๋ฐ ๊ทธ๊ฒŒ ์•„๋‹ˆ๋‹ค ?! 

  • ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
var token=jwt.sign(user._id.toHexString(), 'secretToken')