How to reset / change password in Node.js with Passport.js?

user3044147 picture user3044147 · Nov 29, 2013 · Viewed 25k times · Source

I use Passport.js in Node.js to create a login system. Everything is ok, but I do not know how to reset user password when they forget their password or they want to change it.

User model in MongoDB

var UserSchema = new Schema({
    email: String,
    username: String,
    provider: String,
    hashed_password: String,
    salt: String,
});

Answer

airtonix picture airtonix · Dec 20, 2014

Didn't really like the idea of hitting my database to store tokens, especially when you want to be creating and verifying tokens for many actions.

Instead I decided to copy how Django does it:

  • convert timestamp_today to base36 as today
  • convert user.id to base36 as ident
  • create hash containing:
    • timestamp_today
    • user.id
    • user.last_login
    • user.password
    • user.email
  • salt the hash with a hidden secret
  • create a route like : /change-password/:ident/:today-:hash

We test the req.params.timestamp in order to simply test if it's valid for today, cheapest test first. fail first.

Then we find the user, fail if it doesn't exist.

Then we generate the hash again from above, but with the timestamp from req.params

The reset link becomes invalid if :

  • they remember their password and login (last_login changes)
  • they're actually still logged in and:
    • just change their password (password changes)
    • just change their email (email changes)
  • tomorrow arrives (timestamp changes too much)

This way:

  • you're not storing these ephemeral things in your database
  • when the purpose of the token is to change the state of a thing, and that things state changed, then the purpose of the token is no longer securely relevant.