46 Adding JWT Authentication Middleware
46 Adding JWT Authentication Middleware
Authentication is one of the most crucial aspects of modern web application development. One popular and efficient solution for handling authentication in stateless applications is the JSON Web Token (JWT). In this 46th article of the series, I’ll cover how to add JWT authentication middleware to a Node.js backend (using Express) with a simple case study, code examples, request simulations, and flow diagrams to make it easier to understand. This article is written to help you, whether you’re a beginner or already experienced, understand the process of securing routes using JWT middleware.
A Quick Introduction to JWT (JSON Web Token)
JWT is an open standard (RFC 7519) for securely exchanging information as a JSON object. Why is JWT so popular? Because it’s simple, lightweight, easy to implement, and can be used in modern application architectures such as RESTful APIs.
A JWT consists of three parts:
- Header (information about the token type & signing algorithm)
- Payload (the data you want to share)
- Signature (the hash of header+payload using a secret key)
Example JWT token (truncated):
1eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NSIsImlhdCI6MTY3NjM5MDAwMH0.JstShdk8laNsFnw4rVSdaLRKOa8Aq9s8KfTProblem: Without Authentication Middleware
Before authentication middleware exists, the routes in an application can be accessed freely. Here’s an example of an Express route without authentication:
1app.get('/profile', (req, res) => {
2 res.send('User profile data that should only be accessible to authenticated users');
3});The risk: Anyone can access /profile.
Solution: JWT Authentication Middleware
The Middleware Concept
- Middleware in Express is a function that has access to
req,res, andnext. - It can be used to validate requests, process data, intercept access, and more.
- JWT authentication middleware is responsible for reading and verifying the JWT on every request before passing it on to the route handler.
Authentication Flow Diagram with JWT Middleware
flowchart TD
A[Client mengirim request ke /profile] --> B{Request membawa JWT?}
B -- Tidak --> C[Respon 401 Unauthorized]
B -- Ya --> D[Verifikasi Signature JWT]
D -- Gagal --> C
D -- Berhasil --> E[Ambil Payload JWT]
E --> F[Req diteruskan ke route]
F --> G[Respon Data Profil]
The diagram above shows how invalid requests are intercepted before they reach the handler.
Implementation: Step by Step
Let’s jump straight into building JWT authentication middleware in Express.
1. Install the required packages
1npm install express jsonwebtoken dotenv2. Project Structure (optional)
1/project-root
2├── .env
3├── app.js
4└── middleware/
5 └── jwtMiddleware.js3. Configure the Secret Key (.env)
1JWT_SECRET=myverystrongsecret4. Middleware Implementation (middleware/jwtMiddleware.js)
1// File: middleware/jwtMiddleware.js
2const jwt = require('jsonwebtoken');
3
4function authenticateJWT(req, res, next) {
5 const authHeader = req.headers.authorization;
6
7 if (!authHeader) {
8 return res.status(401).json({ message: 'Token not found' });
9 }
10
11 const token = authHeader.split(' ')[1];
12 // Format: "Bearer <token>"
13
14 jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
15 if (err) {
16 return res.status(401).json({ message: 'Invalid token' });
17 }
18
19 req.user = user; // Store the payload on the request
20 next();
21 });
22}
23
24module.exports = authenticateJWT;5. Using the Middleware on a Route (app.js)
1require('dotenv').config();
2const express = require('express');
3const authenticateJWT = require('./middleware/jwtMiddleware');
4
5const app = express();
6
7app.get('/profile', authenticateJWT, (req, res) => {
8 // req.user is the verified payload
9 res.json({
10 message: 'Hello, ' + req.user.username,
11 data: req.user
12 });
13});
14
15app.listen(3000, () => {
16 console.log('Server running on port 3000');
17});6. Login Simulation: Generating a JWT
To test this, we need a simple login endpoint.
1const jwt = require('jsonwebtoken');
2app.use(express.json());
3
4app.post('/login', (req, res) => {
5 // Simulated user & validation (hard-coded)
6 const { username, password } = req.body;
7 if (username === 'budi' && password === 'rahasia') {
8 // The payload is up to you; typically at least userId / username
9 const payload = { username: username, id: 1 };
10 const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
11 res.json({ accessToken: token });
12 } else {
13 res.status(401).json({ message: 'Invalid username or password' });
14 }
15});Request & Response Simulation
1. Log In and Obtain a Token
- Request
1POST /login 2Content-Type: application/json 3 4{ 5 "username": "budi", 6 "password": "rahasia" 7} - Response
1{ 2 "accessToken": "eyJhbGciOiJIUzI1NiIsInR... (long token)" 3}
2. Access the Protected Route
- Request
1GET /profile 2Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR...(token from login) - Response
1{ 2 "message": "Hello, budi", 3 "data": { 4 "username": "budi", 5 "id": 1, 6 "iat": 1683960600, 7 "exp": 1683964200 8 } 9}
3. Access Without a Token
- Request
1GET /profile - Response
1{ "message": "Token not found" }
Advantages and Disadvantages of JWT Middleware
| Advantages | Disadvantages/Things to Watch Out For |
|---|---|
| Stateless, scalable | The token can be abused if leaked |
| Multi-platform friendly | Not easy to revoke/invalidate |
| Easy to implement | The payload size can grow large |
| Fast (no DB lookup) | Requires expiry & rotation management |
Best Practices & Notes
- Always store the secret key in an environment variable.
- Don’t put sensitive information in the JWT payload.
- Implement an expiry (
exp) on the JWT for extra security. - For complex applications, consider a token blacklist/whitelist mechanism, especially when a user logs out.
Conclusion
Adding JWT authentication middleware is an important step in securing a modern API. With just a little extra code, we can filter out unauthenticated requests and grant access only to valid users according to their JWT payload. This approach is also highly flexible to apply in microservices systems and mobile applications.
I hope this article helps you understand the role of JWT middleware in a structured way. Feel free to remix the code examples above to fit your project’s needs. If you have any questions or want to share your experience implementing JWT in a different technology stack, drop a comment below! 🚀
References: