简体   繁体   English

比较密码 BcryptJS

[英]Compare passwords BcryptJS

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.我正在尝试创建一个用户,然后使用这些凭据登录并取回 JSON Web 令牌。 Where I'm stuck is trying to compare the passwords then send a response.我卡住的地方是尝试比较密码然后发送响应。

Steps:脚步:

Create User:创建用户:

  1. enter email and password输入 email 和密码
  2. salt/hash user password盐/哈希用户密码
  3. store user into database将用户存入数据库
  4. return success返回成功

Login登录

  1. find user by request email value通过请求 email 值查找用户
  2. if found compare passwords如果找到比较密码
  3. passwords good send JSON Web Token密码好的发送 JSON Web Token

User Model用户 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.完全坚持这一点,任何帮助将不胜感激。

As described in the doc , you should use bcrypt.compare like that:文档中所述,您应该像这样使用bcrypt.compare

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这是一篇关于使用 Mongoose 进行密码验证的好文章(第 1 部分):bcrypt

If we you to use bcryptjs in browser(HTML) then you can add bcryptjs CDN to do this.如果您在浏览器(HTML)中使用 bcryptjs,那么您可以添加 bcryptjs CDN 来执行此操作。

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

Example -示例-

HTML - (Add above CDN in tag) HTML - (在标签中添加上面的 CDN)

JS- 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如果你想在 Nodejs 中做同样的事情

/** Import lib like below and use same functions as written above */ /** 像下面这样导入 lib 并使用与上面编写的相同的功能 */

    var bcrypt = require('bcryptjs')
//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

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));
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" })
                }
               })
const bcrypt = require("bcryptjs");
const salt = bcrypt.genSaltSync(10);

const hashPassword = (password) => bcrypt.hashSync(password, salt);
const comparePassword = (password, hashedPassword) =>
  bcrypt.compareSync(password, hashedPassword);


bcrypt.compare(req.body.password, user.password)
            .then(valid => {
                if (!valid) {
                    return res.status(401).json({ message: 'Paire login/mot de passe incorrecte' });
                }
                
                res.status(200).json({
                    userId: user._id,
                    token:jwt.sign(
                        {userId: user._id},
                        process.env.ACCESS_TOKEN_SECRET_KEY,
                         {expiresIn:'24h'}
                    ),
                    message: 'connected'
                });
            })
            .catch(error => res.status(500).json({ error }));



enter code here

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM