当我从 user.password 中提取数据时,Bcryptjs 比较不起作用

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

以下是一些有效代码的测试: 假设所有文件都从 bcryptjs 导入 bcrypt 并且 DB 正在工作。

// Validate Password testing

const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash("testing", salt);

const plaintextPassword = "testing"; // What users should enter in the login form
const storedHash = hashedPassword; // Stored hash in your database

const isValidPassword2 = await bcrypt.compare(
  plaintextPassword,
  storedHash
);
console.log("testing password: " + plaintextPassword);
console.log("testing user.password " + storedHash);
console.log(isValidPassword2); // Should be true if plaintextPassword is correct

// end testing

输出:

testing password: testing
testing user.password $2a$10$k9h8yGCntskaRbPU6cMuPuzovwdn3AUE9JrOx1k74ZYImSAMUnyLa
true

这是我的代码,遵循相同的逻辑,但不起作用:

注册/route.js

// Hash Password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);

// Create new user
const newUser = new User({
  username,
  email,
  password: hashedPassword,
});

登录/route.js

const isValidPassword = await bcrypt.compare(password, user.password);
console.log("password: " + password);
console.log("user.password " + user.password);
console.log(isValidPassword);

输出:我想指出,对于该用户,test4 IS是正确的密码。

password: test4
user.password $2a$10$RtI4wnOtcuJL3N6xpGdFgOrU2ij9aUU4tzTyOwEEX4XpOEmf03iUO
false

用户.js

import mongoose from "mongoose";
import bcrypt from "bcryptjs";

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
});

userSchema.pre("save", async function (next) {
  if (!this.isModified("password")) {
    return next();
  }

  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt);
  next();
});

// Correctly reference the model to prevent overwriting
const User = mongoose.models.Users || mongoose.model("Users", userSchema);

export default User;

我真的不知道发生了什么事。我的用户架构是否会再次重新哈希?但我被告知要这样做以将其存储在数据库中。抱歉,代码转储,谢谢!

javascript bcrypt
1个回答
0
投票

您面临的主要问题是,当您将密码保存给用户时,您拥有密码两次,但在比较密码时仅对其进行哈希一次......因此您所要做的就是删除额外的逻辑在创建用户之前对其进行哈希处理。
每次创建用户时,您都会为该用户创建一个盐,并使用该盐对其密码进行哈希处理...根据This SO answer,bcrypt 使用密码保存盐,该密码告诉它盐是什么。因此,您不需要将盐单独保存在数据库中。当用户登录时,您将其密码与用户存储的哈希密码进行比较。这是一个未经测试的示例,代码如下:

注册:

// Create new user
const newUser = new User({
  username,
  email,
  password: password, //passing plain text password.
}); // We will hash the password when creating it, as well as generate the salt.

创建用户:

import mongoose from "mongoose";
import bcrypt from "bcryptjs";

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  }
});

userSchema.pre("save", async function (next) {
  if (!this.isModified("password")) {
    return next();
  }

  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt); //password gets first hash here. Salt is saved with it by bcrypt.
  next();
});

// Correctly reference the model to prevent overwriting
const User = mongoose.models.Users || mongoose.model("Users", userSchema);

export default User;

登录:

const isValidPassword = await bcrypt.compare(password, user.password); //Behind the scenes bcrypt knows to add the salt in user.password to the plaintext password.

您会注意到,在寄存器中我们所做的就是使用密码创建用户,然后生成盐,并将盐和散列密码保存给用户。
然后当我们登录时,我们传递输入要进行哈希处理(和加盐)的密码,并与数据库中存储的密码(已经经过哈希处理并包含盐)进行比较。

最终,您面临的问题是您对密码进行了两次哈希处理。

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