📝 Introduction
Authentication is a key part of almost every web application today, and JSON Web Tokens (JWT) offer a modern, stateless, and secure way to manage it. If you’ve ever wondered how websites keep you logged in or verify who you are behind the scenes, chances are JWT is involved.
In this article, we’ll break down what JWT is, how it works, and how you can use it to protect your routes and user data. Don’t worry—this guide is written with beginners in mind, with simple code examples and clear explanations.
✅ What You’ll Learn in This Article
- What is JWT and why it’s used
- The structure of a JWT (Header, Payload, Signature)
- How to generate a token using jwt.sign()
- How to decode and verify the token using middleware
- Real-world use case: authenticating users in a Node.js app
- Common mistakes and best practices when using JWT
🔐 What is JWT and Why It’s Used
JWT stands for JSON Web Token — a secure and compact way to send user information between a client and a server. Once a user logs in, the server creates a token containing user data, signs it using a secret key, and sends it back to the client. The client then includes this token in future requests to prove they are authenticated.
JWT is commonly used in stateless authentication. This means the server doesn’t need to remember who the user is—everything is stored in the token and verified on each request.
🧬 The Structure of a JWT
A JWT is made up of three parts, separated by dots (.
):
Header.Payload.Signature
1. 🧾 Header
The header typically contains two pieces of information:
- The type of the token (always JWT)
- The signing algorithm (like HS256)
{
"alg": "HS256",
"typ": "JWT"
}
2. 📦 Payload
The payload contains the actual data (also called claims), such as the user ID or username. You can add custom data too.
{
"id": 1,
"username": "gurnav",
"iat": 1625674832,
"exp": 1625678432
}
- iat: Issued At – when the token was created.
- exp: Expiration – when the token will expire.
3. 🔐 Signature
The signature is created by combining the header, payload, and a secret key. It ensures that the token wasn’t tampered with.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret_key
)
If someone tries to change the data in the payload, the signature won’t match, and the token will be rejected.
🔐 How to Generate a Token Using jwt.sign()
After a user successfully logs in (by entering the correct email and password, for example), we usually want to create a token to identify them in future requests. This is where jwt.sign() comes in.
jwt.sign(payload, secretKey, options)
- payload: Object with user info like ID, username, role, etc.
- secretKey: A string used to sign the token (keep this private!)
- options: An object with additional settings like expiresIn
💡 Code Example: Creating a JWT Token in Node.js
const jwt = require('jsonwebtoken');
const user = {
id: 1,
username: 'gurnav',
};
const secretKey = 'my_secret_key';
const token = jwt.sign(user, secretKey, { expiresIn: '1h' });
console.log('Generated Token:', token);
output
Generated Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
This token can now be:
- Sent back to the client
- Stored in localStorage or cookies
- Used in future requests as a proof of identity
📌 Real-World Use Case
In a real application, you'd generate this token after verifying the user's credentials:
app.post('/login', (req, res) => {
const { username, password } = req.body;
// Fake user authentication (replace with DB check)
if (username === 'gurnav' && password === '123456') {
const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
res.json({ message: 'Login successful', token });
} else {
res.status(401).json({ message: 'Invalid credentials' });
}
});
🛡️ How to Verify a JWT Token Using Middleware
Once a token is created and sent to the client, it’s included in every protected request—usually in the Authorization header or cookie. The server then verifies this token to check if the user is authenticated and allowed to access the route.
We use a middleware function in Node.js (Express) to handle this verification.
✅ Middleware Code Example
const jwt = require('jsonwebtoken');
const secretKey = 'my_secret_key';
function authenticateToken(req, res, next) {
// Get the token from the Authorization header
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer <token>
if (!token) {
return res.status(401).json({ message: 'Access token missing' });
}
// Verify the token
jwt.verify(token, secretKey, (err, user) => {
if (err) {
return res.status(403).json({ message: 'Invalid or expired token' });
}
req.user = user; // Attach the user info to the request
next(); // Proceed to the next middleware or route
});
}
📌 How to Use the Middleware
You can use this authenticateToken middleware on any route you want to protect
app.get('/dashboard', authenticateToken, (req, res) => {
res.json({ message: `Welcome ${req.user.username}!`, user: req.user });
});
Now only users with a valid JWT token will be able to access /dashboard.
🔒 Key Points
Tip: Always send tokens from the frontend using the Authorization: Bearer header.
The jwt.verify() function will:
- "Decode the token"
- "Check its signature"
- "Check for expiration (exp)"
If valid, you can access the decoded user info via req.user
🏁 Conclusion
JWT makes authentication in web applications simple, secure, and scalable—especially for APIs and SPAs. In this article, you learned how to create, structure, and verify JWTs using Node.js.
Now you’re ready to secure your routes like a pro! 🚀
Top comments (1)
good