Module 1: Introduction to Authentication

Learning Objectives

By the end of this module, you should be able to:

  • Explain what authentication is and why it's important
  • Understand the difference between authentication and authorization
  • Implement password hashing using bcrypt
  • Create a basic user registration and login system

Video Lesson

What is Authentication?

Authentication is the process of verifying the identity of a user, system, or entity. It's a way to ensure that users are who they claim to be. In web applications, authentication is typically achieved by requiring users to provide credentials, such as a username and password.

Authentication vs. Authorization

While they sound similar, authentication and authorization are two distinct concepts:

  • Authentication: Verifies who the user is (identity verification)
  • Authorization: Determines what resources a user can access (permission verification)

Think of authentication as showing your ID at a venue entrance (proving who you are), while authorization is like having a VIP pass that determines which areas you can access once inside.

Password Security

One of the most critical aspects of authentication is secure password handling. Never store passwords in plain text! Instead, we use hashing algorithms to securely store passwords.

What is Password Hashing?

Hashing is a one-way function that converts a password into a fixed-length string of characters, which appears random. The same password will always produce the same hash, but it's computationally infeasible to reverse the process.

Using bcrypt for Password Hashing

bcrypt is a password-hashing function designed by Niels Provos and David Mazières. It's based on the Blowfish cipher and incorporates a salt to protect against rainbow table attacks.

const bcrypt = require('bcryptjs');

// Hashing a password
const hashPassword = async (password) => {
  const salt = await bcrypt.genSalt(10);
  const hashedPassword = await bcrypt.hash(password, salt);
  return hashedPassword;
};

// Verifying a password
const verifyPassword = async (password, hashedPassword) => {
  const isMatch = await bcrypt.compare(password, hashedPassword);
  return isMatch;
};

Implementing User Registration

A basic user registration system involves:

  1. Collecting user information (username, email, password, etc.)
  2. Validating user input
  3. Hashing the password
  4. Storing user data in a database

Example: Express.js User Registration Route

const express = require('express');
const bcrypt = require('bcryptjs');
const router = express.Router();

// User registration route
router.post('/register', async (req, res) => {
  try {
    const { username, email, password } = req.body;
    
    // Input validation (simplified)
    if (!username || !email || !password) {
      return res.status(400).json({ message: 'All fields are required' });
    }
    
    // Check if user already exists in database
    const userExists = await User.findOne({ email });
    if (userExists) {
      return res.status(400).json({ message: 'User already exists' });
    }
    
    // Hash the password
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(password, salt);
    
    // Create new user
    const user = new User({
      username,
      email,
      password: hashedPassword
    });
    
    // Save user to database
    await user.save();
    
    res.status(201).json({ message: 'User registered successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Server error', error: error.message });
  }
});

Implementing User Login

A basic user login system involves:

  1. Collecting user credentials (username/email and password)
  2. Finding the user in the database
  3. Comparing the provided password with the stored hash
  4. Creating a session or token upon successful authentication

Example: Express.js User Login Route

// User login route
router.post('/login', async (req, res) => {
  try {
    const { email, password } = req.body;
    
    // Input validation
    if (!email || !password) {
      return res.status(400).json({ message: 'Email and password are required' });
    }
    
    // Find user by email
    const user = await User.findOne({ email });
    if (!user) {
      return res.status(400).json({ message: 'Invalid credentials' });
    }
    
    // Verify password
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(400).json({ message: 'Invalid credentials' });
    }
    
    // Create session or token (we'll cover JWT in Module 2)
    // For now, using session-based authentication
    req.session.user = {
      id: user._id,
      username: user.username,
      email: user.email
    };
    
    res.status(200).json({ message: 'Login successful' });
  } catch (error) {
    res.status(500).json({ message: 'Server error', error: error.message });
  }
});

Additional Resources

Practice Assignment

Now it's time to practice what you've learned! Create a basic Node.js/Express application with user registration and login functionality.

  • Set up a new Express project with necessary dependencies
  • Create a user model with username, email, and password fields
  • Implement registration and login routes with proper password hashing
  • Add basic form validation
  • Create a protected route that requires authentication

Next Steps

In the next module, we'll explore JSON Web Tokens (JWT) for token-based authentication, which is a more modern approach compared to session-based authentication.

Go to Module 2: JWT