Custom database login generate 401 error

I created a custom database using our own MySQL database.

The connection to MySQL works fine.

The user is found in the table.

However, bcrypt.compare aways returns false even though I am sure that the password entered is the correct one.

Here is the script I use:

function login(email, password, context, callback) {
  const mysql = require('mysql');
  const bcrypt = require('bcrypt');

  const connection = mysql.createConnection({
    host: configuration.MYSQL_HOST,
    user: configuration.MYSQL_USER,
    password: configuration.MYSQL_PASSWORD,
    database: configuration.MYSQL_DATABASE
  });

  connection.connect();
	console.log("connected to database");
  
  const query = 'SELECT user_id, firstname, lastname, email, password FROM user WHERE email = ? AND app_org_id = ' + context.organization.metadata.app_org_id;

  connection.query(query, [ email ], function(err, results) {

    if (err) return callback(err);
    if (results.length === 0) return callback(new WrongUsernameOrPasswordError(email));
    const user = results[0];
    
    console.log("user found, user_id is " + user.user_id);
    console.log("comparing password with hash");
    bcrypt.compare(password, user.password, function(err, isValid) {
      if (err || !isValid) {
        console.log("bcrypt.compare failed");
        return callback(err || new WrongUsernameOrPasswordError(email));
      }

      callback(null, {
        user_id: user.user_id.toString(),
        nickname: user.email,
        email: user.email
      });
    });
  });
}

Here is are the logs in Real-time Webtask Logs:

10:09:03 AM:
 connected to database
10:09:04 AM:
 user found, user_id is 616283
10:09:04 AM:
 comparing password with hash
10:09:04 AM:
 bcrypt.compare failed
10:09:04 AM:
 finished webtask request

What could be the problem ?

Hi @malanciault

Thanks for reaching out to Auth0 Community!

On high level i can suggest is that your external database password must be encrypted and that will be compared with the user entered password plain text, if this not happens then bcrypt.compare failed will come.

Also please check this github link with good discussion on this issue who has faced earlier bcrypt.compare always returns false · Issue #906 · kelektiv/node.bcrypt.js · GitHub

previous community post with similar issue

https://community.auth0.com/t/joomla-login-bcrypt-compare-always-false/5163

Hope this helps!

Regards,
Pavan.

Thanks Pavan!

On high level i can suggest is that your external database password must be encrypted and that will be compared with the user entered password plain text, if this not happens then bcrypt.compare failed will come.

I confirm that the password stored in the database is indeed encrypted using PHP password_hash and BCRYPT algorithm.

With the links you mentionned, I came accross this bcrypt.compare return false always. · Issue #685 · kelektiv/node.bcrypt.js · GitHub which solved the problem.

If it can help other people, here is the Database Action Script that worked (using MysQL database)

function login(email, password, context, callback) {
  const mysql = require('mysql');
  const bcrypt = require('bcrypt');

  const connection = mysql.createConnection({
    host: configuration.MYSQL_HOST,
    user: configuration.MYSQL_USER,
    password: configuration.MYSQL_PASSWORD,
    database: configuration.MYSQL_DATABASE
  });

  connection.connect();
  
  const query = 'SELECT user_id, firstname, lastname, email, password FROM user WHERE email = ?';

  connection.query(query, [ email ], function(err, results) {

    if (err) return callback(err);
    if (results.length === 0) return callback(new WrongUsernameOrPasswordError(email));
    const user = results[0];

    const hashPass = /^\$2y\$/.test(user.password) ? '$2a$' + user.password.slice(4) : user.password;
    bcrypt.compare(password, hashPass, function(err, isValid) {
      if (err || !isValid) {
        console.log("bcrypt.compare failed");
        return callback(err || new WrongUsernameOrPasswordError(email));
      }

      callback(null, {
        user_id: user.user_id.toString(),
        nickname: user.email,
        email: user.email
      });
    });
  });
}

1 Like

Hi @malanciault,

Great to here the issue got resolved, and Thank you for sharing the updated code which will definitely help others.

Regards,
Pavan.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.