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:
- Collecting user information (username, email, password, etc.)
- Validating user input
- Hashing the password
- 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:
- Collecting user credentials (username/email and password)
- Finding the user in the database
- Comparing the provided password with the stored hash
- 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