0

I want to send an Email to the user with a link to a login-Page, that includes a hashed password/token/key as a parameter (but not a username).

Then I want to give the user access to the application, if there is an entry with that key in the user database.

My idea was to iterate through the database and looking for a password-match with bcrypt. But it seems bcrypt only returns a promise, not an boolean (as I hoped).

The goal is a one-way-key to the application: the user clicks the link, filled out the form and on submit the useraccount will be deactivated.

What is a common way to solve this problem?

Sönke
  • 45
  • 1
  • 7
  • 1
    I don't see what this has to do with bcrypt or passwords at all. You create a random (unguessable) token, you store it in the database (with an expiry time), you send the link via email. Then when the url is visited, you search for the user which has an entry with that token, you authorise them. – Bergi Jul 25 '22 at 13:29
  • But in the database the token is hashed. So how to compare? Let's say, I iterate through all user-entries to compare the given token with the one in database. I see no way to say "if (bcrypt.compare(givenToken, storedToken)" because it returns a promise. – Sönke Jul 25 '22 at 13:33
  • Oh now I see, you want to hash it like you would hash a password – Bergi Jul 25 '22 at 13:39

1 Answers1

1

It seems bcrypt only returns a promise, not an boolean

That shouldn't be a problem, see How to access the value of a promise?. Just write

if (await bcrypt.compare(givenToken, storedToken)) { … }

or

bcrypt.compare(givenToken, storedToken).then(match => { if (match) … })

My idea was to iterate through the database and looking for a password-match with bcrypt.

No, don't do that, it'll be slow. You would have to check all the users every time, which doesn't scale.

What is a common way to solve this problem?

  • Just don't hash the token in the first place - make sure to create suitably unguessable ones (using a cryptographically strong random generator) and you're fine. The threat model on short-lived access tokens is different than the one on passwords. Store them in the database as they are, then you can easily search in the database for the user account by the token.
  • Do put the username (or id or whatever) next to the token in the login key (url). If you want to make non-forgeable, sign the key; if you want to make it un-identifiable, encrypt the key.
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks a lot for the two answers! The first helps me a lot, but the second will be the way to go for me. – Sönke Jul 26 '22 at 08:59