JWT (JSON Web Token) is a widely used method for handling authentication in modern web applications and APIs. It allows a server to securely send information about a user to a client after login in the form of a digitally signed token. When a user logs into an application, they usually enter their email and password to prove their identity. However, web servers are stateless, which means they don’t remember previous requests. Because of this “forgetful nature,” the server would normally need to re-authenticate the user on every request, which would be inefficient.
This is where JWT (JSON Web Token) comes in. After a successful login, the server generates a signed token and sends it to the client. The client stores this token and sends it with future requests, allowing the server to quickly verify the user’s identity without asking for the password again.
Day 38 was all about what JWT is and how and why it is used
What JWT Is
JWT stands for JSON Web Token.
It is a secure token generated by the server and sent to the client after a successful login.
Example JWT token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
The client stores this token and sends it with future requests to prove authentication.
Typical JWT Authentication Flow
User logs in
↓
Server verifies password
↓
Server generates JWT
↓
Client stores token
↓
Client sends token in future requests
↓
Server verifies token
JWT allows APIs to remain stateless, meaning the server does not need to store session data.
Structure of a JWT
A JWT consists of three parts separated by dots:
HEADER.PAYLOAD.SIGNATURE
Example:
xxxxx.yyyyy.zzzzz
Header
The header defines the algorithm used to sign the token.
Example:
{
"alg": "HS256",
"typ": "JWT"
}
Payload
The payload contains data stored inside the token.
Example:
{
"userId": "12345",
"email": "user@email.com"
}
⚠️ Important:
The payload is not encrypted, only encoded.
So never store sensitive data like passwords in it.
Signature
The signature ensures token integrity.
It is created using:
- the encoded header
- the encoded payload
- a secret key
This prevents attackers from modifying the token.
Installing the JWT Library
In Node.js, we commonly use the jsonwebtoken package.
Install it using npm:
npm install jsonwebtoken
Import it in your project:
const jwt = require("jsonwebtoken");
Generating JWT Tokens (During Login)
When a user logs in successfully, the server generates a token.
Example:
const token = jwt.sign(
{ userId: user._id },
process.env.JWT_SECRET,
{ expiresIn: "1h" }
);
Explanation
| Parameter | Meaning |
|---|---|
| payload | Data stored inside the token |
| secret key | Used to sign and verify the token |
| expiresIn | Token expiration time |
⚠️ Best Practice:
Never hardcode secret keys like "secretkey".
Use environment variables instead.
Example API response:
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}
Sending Token with Requests
After login, the client stores the token and sends it with future requests.
Typically, the token is sent inside the Authorization header.
Example:
Authorization: Bearer TOKEN
Example request header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
The word Bearer indicates that the request is authenticated using a bearer token.
Verifying JWT Tokens
Every protected route must verify the token before allowing access.
Example:
const decoded = jwt.verify(token, process.env.JWT_SECRET);
If the token is valid:
- The request continues.
If the token is invalid or expired:
- The request is rejected.
Creating Authentication Middleware
Middleware helps protect private routes.
Example authentication middleware:
const jwt = require("jsonwebtoken");
function authMiddleware(req, res, next) {
const token = req.headers.authorization?.split(" ")[1];
if (!token) {
return res.status(401).json({ message: "No token provided" });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ message: "Invalid token" });
}
}
This middleware:
- Extracts the token from the header
- Verifies the token
- Attaches the decoded user data to the request
- Allows access to the route if valid
Protecting Routes
Now we can use the middleware to protect routes.
Example protected route:
router.get("/profile", authMiddleware, (req, res) => {
res.json({
message: "Protected profile route",
user: req.user
});
});
Only authenticated users with a valid JWT can access this endpoint.
Complete Authentication Flow
Here is the full authentication process:
User registers
↓
Password hashed
↓
User logs in
↓
Server verifies password
↓
Server creates JWT
↓
Client stores token
↓
Client sends token with requests
↓
Server verifies token
↓
Access granted to protected routes
Final Thoughts
JWT authentication is widely used in modern APIs because it is:
- Stateless
- Secure
- Scalable
- Easy to integrate with frontend applications
By using JWT with middleware in Express, you can easily protect routes and ensure only authenticated users access sensitive resources.
💡 If you're learning backend development, understanding JWT is a core concept for building secure APIs.
Thanks for reading. Feel free to share your thoughts!
Top comments (0)