...

/

Implementing Authentication in Node.js

Implementing Authentication in Node.js

Learn how to implement secure authentication in Node.js using password hashing with bcrypt and stateless authentication with JSON Web Tokens (JWT).

Authentication is a fundamental aspect of any web application, ensuring that users can securely log in and access sensitive resources. In Node.js, authentication requires securely handling user credentials, validating access rights, and managing sessions effectively. To achieve this, developers commonly rely on two key techniques: hashing passwords for secure storage and using JSON Web Tokens (JWT) for stateless authentication.

Together, password hashing and JWTs form a robust foundation for building secure, efficient, and scalable authentication systems in Node.js applications.

Password hashing with bcrypt

Passwords should never be stored in plain text to ensure user security. If a database is compromised, plain-text passwords can be easily exploited, putting all accounts at risk. Instead, passwords should be hashed, transforming them into irreversible strings that cannot be converted back to their original form.

The bcrypt library is a reliable tool for hashing passwords in Node.js. It adds a unique random string, called a salt, to each password before hashing, ensuring that even identical passwords produce different hashes. This approach prevents attackers from using precomputed hash dictionaries, making it much harder to crack passwords. In addition to hashing passwords during registration, bcrypt allows for secure verification during login by comparing the entered password with the stored hash. This ensures user credentials are protected even if the database is compromised.

Press + to interact
Password hashing using bcrypt library
Password hashing using bcrypt library

Here’s how we can use bcrypt to hash a password and see the transformation from the original password to its hashed version:

import bcrypt from 'bcrypt';

const password = 'my_secure_password';

// Hash the password
bcrypt.hash(password, 10)
  .then((hashedPassword) => {
    console.log(`Original Password: ${password}`);
    console.log(`Hashed Password: ${hashedPassword}`);

    // Compare the original password with the hashed password
    return bcrypt.compare(password, hashedPassword)
      .then((isMatch) => {
        console.log(`Password matches: ${isMatch}`);
      });
  })
  .catch((err) => console.error('Error:', err));
Hashing a password using bcrypt

Explanation

  • Line 1: Import the bcrypt library, which is used for securely hashing and verifying passwords.

  • Line 3: Define a plain-text password to simulate what a user might provide during registration.

  • Line 6: Use bcrypt.hash(password, 10) to hash the password. The number 10 represents the salt rounds, which determine how many times the hashing algorithm is applied. More rounds increase security but require more processing time.

  • Lines 8–9: Log the original password and its hashed version to show the transformation from plain text to a secure, irreversible format.

  • Line 12: Use bcrypt.compare(password, hashedPassword) to verify whether the plain-text password matches the hashed password. This simulates the process used during login to validate user credentials.

  • Line 13: Log the result of the comparison. If the plain-text password matches the hash, isMatch will be true. Otherwise, it will be false.

Run the node index.js command multiple times to observe how the hashed password changes each time, even though the original password remains the same. This variation occurs because bcrypt generates a unique salt for each hashing operation. The salt is embedded directly into the hash, along with other details, and processed through the bcrypt algorithm. This design ensures that the resulting hash includes all the information necessary for secure password verification.

Applying bcrypt to user registration

Now that we’ve seen how bcrypt hashes passwords, let’s apply this knowledge to a real-world scenario: registering a new user.  During user registration, securely handling passwords is essential. In a plain Node.js application, the ...