简体   繁体   English

bcrypt nodejs不断返回false

[英]bcrypt nodejs keeps returning false

I have been struggling with this for hours and have tried a lot of different variations I have found around the web and also on stack overflow but I keep getting stuck on the same thing.我已经为此苦苦挣扎了几个小时,并尝试了很多不同的变体,我在 web 和堆栈溢出中发现了很多不同的变体,但我一直卡在同一件事上。

This is my registration code:这是我的注册码:

// REGISTER USER
app.post("/register", async (request, response) => {
    const saltRounds = 10;
    const emailAddress = request.body.emailAddress;
    const password = await bcrypt.hash(request.body.password, saltRounds);

    console.log(password)

    // CHECK IF A USER EXISTS
    const sqlSearch = "SELECT * FROM users WHERE emailAddress = ?"
    const search_query = mysql.format(sqlSearch, [emailAddress])

    // INSERT NEW USER
    const sqlInsert = "INSERT INTO users (emailAddress, password) VALUES (?,?)"
    const insert_query = mysql.format(sqlInsert, [emailAddress, password])

    await usersDB.query(search_query, async (err, result) => {
        if (err) throw (err)
        if (result.length != 0) {
            console.log("------> User already exists")
            response.send("exists")
        } else {
            await usersDB.query(insert_query, (err, result) => {
                if (err) throw (err)
                response.send("created")
            })
        }
    })
})

This is my login code:这是我的登录代码:

// LOGIN (AUTHENTICATE USER)
app.post("/login", async (request, response) => {
    const emailAddress = request.body.emailAddress
    const password = request.body.password

    const sqlSearch = "SELECT * FROM users WHERE emailAddress = ?"
    const search_query = mysql.format(sqlSearch, [emailAddress])

    await usersDB.query(search_query, async (err, result) => {
        if (err) throw (err)
        if (result.length == 0) {
            console.log("--------> User does not exist")
            response.sendStatus(404)
        } else {
            // Get the hashed password from result
            const hashedPassword = result[0].Password

            await bcrypt.compare(password, hashedPassword, function(err, result) {
                if (result) {
                    console.log("---------> Login Successful")
                    response.send(`${emailAddress} is logged in!`)
                } else {
                    console.log("---------> Password Incorrect")
                    console.log(password)
                    console.log(hashedPassword)
                    response.send("Password incorrect!")
                }
            });
        }
    })
})

I don't really understand what is going wrong in the compare considering the hashes are the same, I also tried pulling the salt rounds out and declaring them as a variable as you can see, this was recommended on another answer.考虑到哈希值相同,我真的不明白比较中出了什么问题,我还尝试将盐轮拉出来并将它们声明为变量,如您所见,这是在另一个答案中推荐的。 I have changed the compare await in several different ways but they all give the same result.我已经以几种不同的方式更改了比较等待,但它们都给出了相同的结果。

I did also check the typeof on each var and they are all strings as they need to be.我还检查了每个 var 上的 typeof,它们都是字符串,因为它们需要是。

My output: The first hash you see is what is going into the database, the password being "test" and the second hash is from the compare statement along with the plaintext being shown.我的 output:您看到的第一个 hash 是进入数据库的内容,密码是“test”,第二个 hash 来自与显示的比较语句一起显示的纯文本。

$2b$10$wXGSrneIiovWHG7wk6a0BOIXwhzelTlCcxeoLsVJ8Au4iiOcoBBhe
---------> Password Incorrect
test
$2b$10$wXGSrneIiovWHG7wk6a0BOIXwhzelTlCcxeoLsVJ8Au4iiOcoBBhe

Any help would be greatly appreciated.任何帮助将不胜感激。

Note: The password column in my DB is a VARCHAR(255)注意:我的数据库中的密码列是 VARCHAR(255)

You can make a 2 seperate function for achieve the bcrypt functions.您可以制作 2 个单独的 function 来实现 bcrypt 功能。 Here is the helper file which holds the bcrypt functions这是保存 bcrypt 函数的帮助文件

const logger = require('./logger');
const bcrypt = require('bcrypt');


const encryptUtil = {};

// It make a hash password
encryptUtil.oneWayEncrypt = async (text) => {
  try {
    const salt = await bcrypt.genSalt(parseInt(process.env.SALT_ROUND, 10));
    const encoded = await bcrypt.hash(text, salt);
    return { encoded, salt };
  } catch (err) {
    logger.error('[ERROR] From oneWayEncrypt in encryptUtils', err);
    throw err;
  }
};

// It will validate plain text with the hashed one
encryptUtil.validateBcryptHash = async (text, hash) => {
  try {
    const isExactMatch = await bcrypt.compare(text, hash);
    return isExactMatch;
  } catch (err) {
    logger.error('[ERROR] From validateBcryptHash in encryptUtils', err);
    throw err;
  }
};

module.exports = encryptUtil;

Here is the usecase of that function in signup and login这是注册和登录中 function 的用例

const encryptUtil = require('../../../helper/encryptUtil');
const logger = require('../../../helper/logger');
const jwt = require('../../../helper/jwt');

const userUtils = {};

userUtils.signUp = async (obj) => {
  try {
    const { name, password } = obj;
    const email = obj.email.toLowerCase();
    const condition = { email };
    const querying = {
      attributes: ['id', 'name', 'email''],
      where: { email },
    };
    const isEmailExist = await Model.user.findOne(querying);
    if (isEmailExist) {
      const errorObj = { code: 400, error: l10n.t('ERR_EMAIL_ALREADY_EXIST') };
      throw errorObj;
    }
    const { encoded: encPassword } = await encryptUtil.oneWayEncrypt(password);
    const insertObj = {
      name,
      email,
      password: encPassword,
    };
    const result = await Model.user.create(insertObj);
    const userId = result.id;
    const token = jwt.getAuthToken({ userId });
    return { token, msg: l10n.t('MSG_SIGNUP_SUCCESS'), user: { name, email, userId } };
  } catch (error) {
    logger.error('[ERROR] From signUp in userUtils', error);
    throw error;
  }
};

userUtils.login = async (obj) => {
  try {
    const { password } = obj;
    const email = obj.email.toLowerCase();
    const querying = {
      attributes: ['id', 'name', 'email', 'password'],
      where: { email },
    };
    const user = await Model.user.findOne(querying);
    if (!user) {
      const errorObj = { code: 400, error: l10n.t('ERR_CREDENTIAL_NOT_MATCHED') };
      throw errorObj;
    }
    // Here it validates the simple text with hashed text which store in a dbatabase
    const isExactMatch = await encryptUtil.validateBcryptHash(password, user.password);
    if (!isExactMatch) {
      const errorObj = { code: 400, error: l10n.t('ERR_CREDENTIAL_NOT_MATCHED') };
      throw errorObj;
    }
    const token = jwt.getAuthToken({ userId: user.id });
    const result = {
      token,
      user: {
        userId: user.id,
        name: user.name,
        email: user.email,
    };
    return result;
  } catch (error) {
    logger.error('[ERROR] From login in userUtils', error);
    throw error;
  }
};

module.exports = userUtils;

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

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