使用 bcrypt 通过跨语言哈希验证密码

问题描述 投票:0回答:1

我有一个存储用户凭据的数据库,其中的密码由 Yii2 函数哈希,即

Yii::$app->getSecurity()->generatePasswordHash($password);

有没有正确的方法使用node.js 验证密码?一直在尝试这段代码,但不断返回

false

bcrypt.compare(plainTextPassword, hashedPasswordFromYii2, (err, res) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(res); // Should output true if the passwords match
}); 

这里是来自 yii2 源的哈希生成器的源代码

protected function generateSalt($cost = 13)
{
    $cost = (int) $cost;

    if ($cost < 4 || $cost > 31) {
        throw new InvalidArgumentException('Cost must be between 4 and 31.');
    }

    // Get a 20-byte random string
    $rand = $this->generateRandomKey(20);

    // Form the prefix that specifies Blowfish (bcrypt) algorithm and cost parameter.
    $salt = sprintf('$2y$%02d$', $cost);

    // Append the random salt data in the required base64 format.
    $salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22));

    return $salt;
}

public function generatePasswordHash($password, $cost = null)
{
    if ($cost === null) {
        $cost = $this->passwordHashCost;
    }

    if (function_exists('password_hash')) {
        /* @noinspection PhpUndefinedConstantInspection */
        return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
    }

    $salt = $this->generateSalt($cost);
    $hash = crypt($password, $salt);

    // strlen() is safe since crypt() returns only ascii
    if (!is_string($hash) || strlen($hash) !== 60) {
        throw new Exception('Unknown error occurred while generating hash.');
    }

    return $hash;
}

请帮忙,任何建议都会有帮助

php node.js express passwords bcrypt
1个回答
0
投票

Node js 是 php 的替代品。在 Node.js 中你想要的东西会更容易。当您使用密码注册新用户时,在存储结果之前首先会像这样进行哈希处理:

userSchema.pre("save", async function(next){
if(!this.isModified('password')){
    next();
}
const salt = bcrypt.genSaltSync(10);
this.password = await bcrypt.hash(this.password, salt);

});

然后与登录密码进行比较,如下所示:

userSchema.methods.isPasswordMatched = async function(enteredPassword){
return await bcrypt.compare(enteredPassword, this.password);

};

现在剩下的就是创建用户模式的实例并在登录时比较密码,如下所示:

const loginUserCtrl = asyncHandler(async (req, res) => {
const {email, password} = req.body;
const findUser = await User.findOne({email});
if(findUser && (await findUser.isPasswordMatched(password))){
    const refreshToken = generateRefreshToken(findUser?.id);
    const updateUser = await User.findByIdAndUpdate(findUser.id,
        {
            refreshToken: refreshToken,
        },
        {new: true
        });

    res.cookie('refreshToken', refreshToken, {httpOnly: true, maxAge: 72*60*60*1000});
    
    res.json({
        _id: findUser?._id,
        firstName: findUser?.firstName,
        lastName: findUser?.lastname,
        email: findUser?.email,
        mobile: findUser?.mobile,
        token: generateToken(findUser?._id),
    });
}else{
    throw new Error("Invalid credentials");
}
console.log(email, password);

});

© www.soinside.com 2019 - 2024. All rights reserved.