Skip to content

Passwords, Hashing, and Salts

When a user registers for an account, we do not store the password.

Storing passwords in plain text is a catastrophic architectural failure. If a database is ever compromised, plain text passwords mean every one of your users is instantly exposed. And since people notoriously reuse passwords across services… well, you don’t want to be the reason someone’s email gets hacked.

Instead, we store a password hash.

People often misuse the word “encryption” here.

  • Encryption is a two-way street: you jumble the data up, and with the right key, you can un-jumble it back into the original plain text.
  • Hashing is a one-way trip. You take a password, grind it through a complex algorithm, and you get a completely unrecognizable string of characters out the other end. You cannot mathematically reverse a hash back into a password.

When a user tries to log in, we take the password they just typed, hash it, and compare it to the hash stored in the database. If they match, it’s the right password. We never need to know the actual plain text string.

What if two users happen to have the exact same terrible password, like P4ssw0rd!? The generated hashes would look identical! A hacker could use a pre-computed “rainbow table” of common hashes to figure out the original passwords.

This is where a salt comes in. A salt is a random string of characters added to a password before it gets hashed. This guarantees that even identical base passwords will produce completely different, unique hashes.

T.A. Watts Note: We use the bcrypt library to do the heavy lifting here. It handles both the hashing and the salting seamlessly.

What we will store in MongoDB:

  • passwordHash (a long, scrambled string).

What we will NEVER store in MongoDB under any circumstances:

  • password
  • passwordEncrypted
  • rawPassword

Bcrypt npm package


📘 Passwords, Hashing, and Salts Infographic (PNG)


We have our scrambled passwords. Let’s hire our bouncer.