简体   繁体   English

在 nodejs 中使用 bcrypt 进行密码散列

[英]Password hashing using bcrypt in nodejs

I am using "bcrypt": "^3.0.4" and I have the latest stable version of node.我正在使用"bcrypt": "^3.0.4"并且我有最新的稳定版本的节点。 The issue I am facing is when the user attempts to login.我面临的问题是用户尝试登录时。 With the correct password the initial login attempt is always unsuccessful while the second attempt is successful.使用正确的密码,首次登录尝试总是不成功,而第二次尝试成功。 I would like to know where I am getting it wrong.我想知道我在哪里弄错了。 The assumption here is that the user has entered an email/username that is available in the database, mongodb in this case.此处假设用户输入了数据库中可用的电子邮件/用户名,在本例中为 mongodb。

User.findOne({ "email": user.email }, (err, ruser) => {
    if (err) {
        res.send(err);
    }
    else {
        bcrypt.hash(user.password, 10, function (err, hash) {
            if (err) {
                console.log(err);
            }
            else {
                bcrypt.compare(user.password, hash).then(function (res) {
                    if (res) {
                        pass = true;
                    }
                    else {
                        pass = false;
                    }
                });
                res.json(pass);
            }
        });
    }
});

Thank you in advance.先感谢您。

There are two issues with your code. 您的代码有两个问题。

  1. bcrypt.compare is async and the res.json is outside of the .then, so res.json is actually ran before comparison or pass it set. bcrypt.compare是异步的,并且res.jsonres.json之外,因此res.json实际上是在比较或pass设置之前运行的。

  2. pass is not defined with var / let , so pass becomes a global variable and this is serious security implication, because two user logging in at the same time will cause a race condition (eg pass from session A may be res.json-ed in session B) pass没有用var / let定义,所以pass成为一个全局变量,这对安全性有严重的影响,因为两个用户同时登录将导致竞争状态(例如,来自会话A的pass可能是res.json-ed B场)

It works as a result of the above two errors, in the first request, res.json is executed before comparison and pass is not set yet, so it returns null. 由于上述两个错误,它的工作原理是:在第一个请求中,在比较之前执行res.json ,并且尚未设置pass ,因此它返回null。 On the second request, again res.json is executed before compare, however this time the pass contains the value of the last compare, so what you are getting is actually last compare's result. 在第二个请求上,再次在比较之前执行res.json ,但是这次pass包含了上次比较的值,因此您得到的实际上是上次比较的结果。

In addition, it is ok if you are just testing, otherwise this code does nothing, because this code generates the hash for the given password, and compares the given password to the generated hash, which definitely should be always true. 此外,如果您只是进行测试就可以,否则此代码不执行任何操作,因为此代码将生成给定密码的哈希值,并将给定密码与生成的哈希值进行比较,该哈希值应始终为true。

import { hash, compare } from 'bcryptjs';

export const hashPassword = async (password: string): Promise<string> => {
  const hashedPassword = await hash(password, 10);
  return hashedPassword;
};

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

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