kelektiv / node.bcrypt.js

bcrypt for NodeJs
MIT License
7.38k stars 510 forks source link

bcrypt generating different hash when assigning same hash #1027

Open Sameerthe-Big-O opened 3 months ago

Sameerthe-Big-O commented 3 months ago

I've run into the same problem which's like compare always returns false but with some strange behaviour.

so I've tried every solution which in previous closed (bcrypt returning false) were mentioned(mostly regarding the length issue)

But here's strange thing behavior I found

const hashpassword = await bcrypt.hash(password, salt)
        console.log(hashpassword)

        user.password = hashpassword

the thing is here hashpassword is

$2b$10$8UMFhEZrwc85vytIGyE2v.mX3CYU/ANojK8ZeaO2bXPs5Lttis7sq but after storing this hash in a variable and storing into the db I found the hash was different

$2b$10$ELPnmKkLLvrPW7QCVSrIp.c3Jn5VuoTsEL7OKnJ5QnJe6ZC2jYb6q why is that assigning to the variable and storing in database making different hash

i've also tried this

 user.password = await bcrypt.hash(password, salt)

where I'm storing the hash directly and literally I've manually compared the hash and hash is same but it doesn't seem to work at this point, I've given up

I'm using MongoDB and Mongoose and here's my schema constraint(length tries)

  password: {
            type: String,
        },
    I have also  tried
      password: {
            type: String,
            maxlength:60
},
    password: {
            type: String,
            maxlength:1000
},

The interesting part here is that it works on the simple register/login user fine for example

userSchema.pre('save', async function () {
    const salt = await bcrypt.genSalt(10)
    if (!this.password) return
    this.password = await bcrypt.hash(this.password, salt)
})

when I try to log in it'll actually work fine and compare doesn't return false package version

   "bcrypt": "^5.1.1",

OS Version

   10.0.22621 Build 22621
EdzonBolivar11 commented 3 months ago

same issue

Sameerthe-Big-O commented 3 months ago

same issue

Hy i just found the bug what went wrong after spinning my head all day uf you're using the userSchema.pre('save', async function () { const salt = await bcrypt.genSalt(10) if (!this.password) return this.password = await bcrypt.hash(this.password, salt) })

this the behaviour you've encounter is expected lemme tell you why is that
so the thing is that whenever we save the user.save() what mongo db does is actually re run this middleware

so you're something like that user.name='sameer' and then user.password = await bcrypt.hash(password, salt) this won't work because we're directly assigning the

H-57 commented 3 months ago

same issue

ashwin1005 commented 2 months ago

The issue arises from pre-save hooks, which are middleware functions invoked before the document is saved, being called before the document is saved. This results in the generation of different hashed passwords.

pls check your schema. @H-57 @EdzonBolivar11