Authentication is a critical aspect of any web application, ensuring that only authorized users can access certain resources. In this tutorial, we will explore how to implement secure authentication mechanisms using Express.js. We'll cover the basics of setting up authentication and discuss best practices to ensure your application remains secure.
Before diving into implementation details, let's understand the key concepts involved in securing user authentication:
First, let's set up a basic Express.js application:
$ npm init -y$ npm install express body-parser bcryptjs jsonwebtoken
Create an app.js file with the following content:
1const express = require('express');2const bodyParser = require('body-parser');3const bcrypt = require('bcryptjs');4const jwt = require('jsonwebtoken');56const app = express();7const port = 3000;89app.use(bodyParser.json());1011// In-memory user storage12let users = [];1314app.listen(port, () => {15console.log(`Server running at http://localhost:${port}`);16});
We'll create a route to register new users. Passwords will be hashed before storing them.
1app.post('/register', async (req, res) => {2const { username, password } = req.body;34// Hash the password5const salt = await bcrypt.genSalt(10);6const hashedPassword = await bcrypt.hash(password, salt);78// Store the user in memory9users.push({ username, password: hashedPassword });1011res.status(201).send('User registered successfully');12});
Next, we'll create a login route that verifies user credentials and returns a JWT.
1app.post('/login', async (req, res) => {2const { username, password } = req.body;34// Find the user5const user = users.find(u => u.username === username);6if (!user) return res.status(401).send('User not found');78// Compare passwords9const isPasswordValid = await bcrypt.compare(password, user.password);10if (!isPasswordValid) return res.status(401).send('Invalid password');1112// Generate a token13const token = jwt.sign({ username: user.username }, 'your_secret_key', { expiresIn: '1h' });1415res.json({ token });16});
Now, let's create a protected route that requires authentication using the JWT.
1const authenticateToken = (req, res, next) => {2const authHeader = req.headers['authorization'];3const token = authHeader && authHeader.split(' ')[1];45if (!token) return res.sendStatus(401);67jwt.verify(token, 'your_secret_key', (err, user) => {8if (err) return res.sendStatus(403);9req.user = user;10next();11});12};1314app.get('/protected', authenticateToken, (req, res) => {15res.json({ message: 'This is a protected route', user: req.user });16});
You can test the application using tools like Postman or curl.
By following these steps and best practices, you can implement secure authentication mechanisms in your Express.js applications. This will help protect your application from common security vulnerabilities and ensure that only authorized users can access sensitive resources.