bcrypt Error: data and hash arguments required
Asked Answered
B

17

32

I am getting a bcrypt error stating that data and hash arguments are required, referencing line #44 in my routes.js file. From what I can tell, I am passing that information: the first parameter to bcrypt.compare is the user entered password, and the second is the hashed password retrieved from the db. What am I doing wrong?

bcrypt.compare(req.params.password, user.password, function...

routes.js

'use strict'

var express = require('express');
var router = express.Router();
var User = require('../app/models/user');
//password hashing
var bcrypt = require('bcrypt');

var count = 0;

router.use(function(req, res, next) {
    count++;
    console.log('API hit count = %s', count);
    next();
});

// /users post(create new user) get(specific user)
router.route('/users')
    .post(function(req,res) {
        var user = new User();
        user.username = req.body.username;
        user.password = bcrypt.hashSync(req.body.password, 10);

        //save the user and checkfor errors
        user.save(function(err) {
            if (err) {
                res.send(err);
            } else {
                res.json({message: "User created!"});
            }    
        });

    })

router.route('/users/:username')
    .get(function(req, res) {
        var query = {
            username: req.params.username,
        };
        User.findOne(query, function(err, user) {
            if (err) { 
                res.send(err);
            } else {
                bcrypt.compare(req.params.password, user.password, function(err, res) {
                    if(err) {
                        console.log('Comparison error: ', err);
                    }
                })
                res.json(user);
            }
        });
    })
Bywoods answered 15/2, 2017 at 5:5 Comment(2)
Set a breakpoint right before bcrypt.compare is called and see what req.params.password and user.password are.Aceous
@Aceous Dammit, I had a mistake in my app.js, sending in an undefined password. Thanks for helping.Bywoods
M
50

bcrypt.compare takes 3 parameters; passwordToCheck, passwordHash, and a callback, respectively. (Check the documentation for examples)

This error means one or both of the first 2 parameters are either null or undefined. Therefore, make sure both of them are passed correctly. (Not as null or undefined)

Mersey answered 4/6, 2017 at 14:51 Comment(2)
This can also happen when you are using arrow function syntax, instead of normal function() syntax. So, make sure to use the latter syntax if you want to preserve this coming from the model, i.e., when pulling something out of the current schema. This saved my day. Thanks!!!Syst
The await syntax does not require the third argument. My issue was one of the two arguments did not have the value I expected, so fixing that fixed this issue.Pelotas
G
8

Why do we face this error? bcrypt Error: data and hash arguments required

Example: bcrypt.compare(first, second)

Ans: because either second key hash password does not exist (null or undefined) or first, which are compared to each other.

Gazette answered 13/8, 2021 at 11:34 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker.Reggie
C
5

I used

const user = await User.find({email: req.body.email}) //which returned all users

//and unless i reference the first user in index 0, i can't pass user.password to the //bcrypt compare method because it's not a string I changed it to

await User.findOne({email: req.body.email})//from which i can use user.password in the //bcrypt compare method
Cimmerian answered 24/3, 2020 at 16:8 Comment(0)
P
4

I was having the same error when I was working with node js and mongoose. It was caused by attribute added to password called select: false in user model.

After remove it, it works.

Pedro answered 11/2, 2022 at 8:3 Comment(1)
this was what I encountered too, pretty disgusting bug but thanks to god I've found it before losing hours :DQuartzite
J
2
const passwordMatch = await bcrypt.compare(password, user.password);

Make sure you are giving raw password and hash password. This will return a boolean value.

Jameejamel answered 27/8, 2020 at 21:54 Comment(0)
E
0

I had the same error and the problem was a missing await when calling the function that reads from database

Enchiridion answered 27/7, 2020 at 17:34 Comment(0)
N
0

I was having the same issue, but I was using the synchronous form of bycrypt.compare(), which is bcrypt.compareSync(), so I changed it to bcrypt.compare() and it works perfectly.

Neolithic answered 20/5, 2021 at 9:21 Comment(0)
H
0

the steps for this problem : 1-ensure that the bcrypt function is have awir before it 2- if the problem is still exist ,then the problem is in the database (mongodb),try to create new database an example:

const match = await bcrypt.compare(password,userValid.password);
            if (match) {
                res.send("login successful")
            }else{
                res.send("wrong password")
            }
        }
Halfdan answered 26/3, 2022 at 20:56 Comment(0)
H
0

Use

findOne({})

instead of

find()

Try console.log() to view and verify the data.

Hamford answered 12/7, 2022 at 12:6 Comment(0)
T
0
try {
    let match  = await bcrypt.compare(password, user.password)
    if(!match){
        return  res.json({mass: "invalid Created"})
    }else{
       res.send('Wrong password')
    }

    console.log('success fulli', user)
    res.render('pages/auth/login', {title: 'Login In Your Account'})

} catch(e) {
    console.log(e)
    next(e)
}
Trass answered 18/7, 2022 at 5:59 Comment(1)
Can you explain this code please?Overstock
D
0

The problem also can appear when you forget to add await when loading data from the database. I got the same error after forgetting to add "await".

let user = User.findOne({ username: req.body.username });

let user = await User.findOne({ username: req.body.username });

Diverticulitis answered 8/11, 2022 at 14:24 Comment(0)
L
0

I also have this problem i set for password select:false in user model and solved by adding select('+password') to login route

Launch answered 13/1, 2023 at 9:0 Comment(0)
A
0

i know all the questions are solved but maybe someone finds this code works for him

const passwordMatch = await bcrypt.compare(password, user.rows[0].s_password);

The name after the dot it's the name you use in your database, it's the field

Automotive answered 26/1, 2023 at 2:16 Comment(1)
Btw i'm using flutter and nodejsAutomotive
H
0

I had the same issue, found out that I had missed an await while comparing hence receiving a null value when comparing.

// Compare incoming & stored password
const matchedPassword = await bcrypt.compare(password, userExists.password)

Also, the first argument should be the plain text password while the second is the hashed password.

Hoarhound answered 8/3, 2023 at 19:34 Comment(0)
L
0

Okay guys huddle up!

First of all if you have "select":false for password in your schema, you should use it like this:

const {email,passord} = req.body

const user = await User.findOne({ email }).select('+password'); // that will allow us the edit password property without revealing it.

After that you can call your compare function

if (!(await user.comparePassword(password, user.password))) {
      res.status(400).json({
        status: 'Fail',
        msg: 'Incorrect nickname or password',
      });
    }
Lagomorph answered 12/3, 2023 at 16:4 Comment(0)
F
0

I also faced the same problem. I realized that usermodel.find() returns an array of all users but users.findOne() returns an object. You should use the latter.

Favela answered 15/5, 2023 at 1:38 Comment(0)
D
0

I was using prisma for finding the user with unique email address, in my case the problem was I was selecting the fields without setting the field names to true :

const user = await prisma.user.findUnique({
  where: {
    email: email,
  },
  select: {
    email,
    password,
    username,
    id
  },
});

I was able to resolve the issue by explicitly setting the select fields to true:

const user = await prisma.user.findUnique({
  where: {
    email: email,
  },
  select: {
    email: true,
    password: true,
    username: true,
    id: true,
  },
});

It worked like a charm afterwards! cheers

Darleen answered 19/5 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.