Compare passwords BcryptJS

醉酒当歌 提交于 2021-02-17 14:54:44

问题


So I'm trying to build a very basic user login. I'm trying to create a user, then login with those credentials and get back a JSON Web Token. Where I'm stuck is trying to compare the passwords then send a response.

Steps:

Create User:

  1. enter email and password
  2. salt/hash user password
  3. store user into database
  4. return success

Login

  1. find user by request email value
  2. if found compare passwords
  3. passwords good send JSON Web Token

User Model

email:{ 
  type: String,
  required: true,
  unique: true
},
password: {
  type: String,
  required: true
}

User Routes

var express     = require('express');
var router      = express.Router();
var jwt         = require('jsonwebtoken');
var bcrypt      = require('bcryptjs');

// Create User
...
bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash("superSecret", salt, function(err, hash) {
      user.password = hash;
      user.save();
      res.json({success: true, message: 'Create user successful'});
    });
  });
...

// Login
...
bcrypt.compare(req.body.password, 'superSecret', function(err, res) {
  if(req.body.password != user.password){
    res.json({success: false, message: 'passwords do not match'});
  } else {
    // Send JWT
  }
});

So the two problems here is that, I can't send a response nor can I compare the password. Just completely stuck on this, any help would be greatly appreciated.


回答1:


As described in the doc, you should use bcrypt.compare like that:

bcrypt.compare(req.body.password, user.password, function(err, res) {
  if (err){
    // handle error
  }
  if (res)
    // Send JWT
  } else {
    // response is OutgoingMessage object that server response http request
    return response.json({success: false, message: 'passwords do not match'});
  }
});

And here is a nice post about Password Authentication with Mongoose (Part 1): bcrypt




回答2:


If we you to use bcryptjs in browser(HTML) then you can add bcryptjs CDN to do this.

CDN - https://cdn.jsdelivr.net/npm/bcryptjs@2.4.3/dist/bcrypt.js

Example-

HTML- (Add above CDN in tag)

JS-

    var bcrypt = dcodeIO.bcrypt;

    /** One way, can't decrypt but can compare */
    var salt = bcrypt.genSaltSync(10);

    /** Encrypt password */
    bcrypt.hash('anypassword', salt, (err, res) => {
        console.log('hash', res)
        hash = res
        compare(hash)
    });

    /** Compare stored password with new encrypted password */
    function compare(encrypted) {
        bcrypt.compare('aboveusedpassword', encrypted, (err, res) => {
            // res == true or res == false
            console.log('Compared result', res, hash) 
        })
    }

If you want to do same in Nodejs

/** Import lib like below and use same functions as written above */

    var bcrypt = require('bcryptjs')



回答3:


From what I can see your logic is correct.

If you are using mongoose I suggest you to use the pre 'save' hook.

User Schema

userSchema.pre('save', function(next) {
  // only hash the password if it has been modified (or is new)
  if (!this.isModified('password')) {
    return next();
  }
  // generate a salt
  return bcrypt.genSalt(10, function(error, salt) {
    if (error) {
      return next(error);
    }

  // hash the password using the new salt
    return bcrypt.hash(this.password, salt, function(error, hash) {
      if (error) {
        return next(error);
      }
      // override the cleartext password with the hashed one
      this.password = hash;
      return next();
    });
  });
});


userSchema.methods.comparePassword = function(passw, cb) {
  bcrypt.compare(passw, this.password, function(err, isMatch) {
    if (err) {
      return cb(err, false);
    }
    return cb(null, isMatch);
  });
};

And in your routes:

Login

...
return user.comparePassword(password, function(error, isMatch) {
  var payload = {
  iat: Math.round(Date.now() / 1000),
  exp: Math.round((Date.now() / 1000) + 30 * 24 * 60),
  iss: 'Whatever the issuer is example: localhost:3000',
  email: user.email
  };

  var token = jwt.encode(payload, 'secret');
  if (isMatch && !error) {
    // if user is found and password is right create a token
    return res.json({
      success: true,
      token: `JWT ${token}`,
      user: user,
      msg: 'Authentication was succesful'
      });
    }
    return next({code: 401, msg: 'Password is incorrect'});
  });
});

Create user

// Pre hook will take care of password creation
return user.save()
.then(function(user) {
  var payload = {
  iat: Math.round(Date.now() / 1000),
  exp: Math.round((Date.now() / 1000) + 30 * 24 * 60),
  iss: 'Whatever the issuer is example: localhost:3000',
  email: user.email
  };

  var token = jwt.encode(payload, 'secret');
  return res.status(201).json({user, token: `JWT ${token}`, msg: 'User was succesfully created'});
})
.catch((err) => next(err));



回答4:


//required files
const express = require('express')
const router = express.Router();

//bcryptjs
const bcrypt = require('bcryptjs')

//User modal of mongoDB
const User = require('../../models/User')


//Post request for login
router.post('/', (req, res) => {
    //email and password
    const email = req.body.email
    const password = req.body.password

    //find user exist or not
    User.findOne({ email })
        .then(user => {
            //if user not exist than return status 400
            if (!user) return res.status(400).json({ msg: "User not exist" })

            //if user exist than compare password
            //password comes from the user
            //user.password comes from the database
            bcrypt.compare(password, user.password, (err, data) => {
                //if error than throw error
                if (err) throw err

                //if both match than you can do anything
                if (data) {
                    return res.status(200).json({ msg: "Login success" })
                } else {
                    return res.status(401).json({ msg: "Invalid credencial" })
                }

            })

        })

})

module.exports = router



回答5:


bcrypt.compare(req.body.password, user.password, function(err, results){
                if(err){
                    throw new Error(err)
                 }
                 if (results) {
                    return res.status(200).json({ msg: "Login success" })
                } else {
                    return res.status(401).json({ msg: "Invalid credencial" })
                }
               })


来源:https://stackoverflow.com/questions/40076638/compare-passwords-bcryptjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!