How to use JWT for authentication on Node.js
Authentication is one of the most important parts of any modern web application.
One of the most popular solutions today is JWT (JSON Web Token).
🤔 What is JWT?
JWT (JSON Web Token) is a compact, URL-safe token used to securely transmit information between parties.
A JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
It consists of three parts:
HEADER.PAYLOAD.SIGNATURE
🧩 JWT Structure
1️⃣ Header
Contains token type and signing algorithm.
{
"alg": "HS256",
"typ": "JWT"
}
2️⃣ Payload
Contains user data (claims).
{
"id": 42,
"email": "user@example.com"
}
⚠️ Never store passwords or sensitive data in payload
3️⃣ Signature
Used to verify the token wasn’t modified.
HMACSHA256(base64UrlHeader + "." + base64UrlPayload, secret)
🔄 How JWT Authentication Works
- User logs in with email & password
- Server verifies credentials
- Server generates a JWT
- Client stores JWT (usually in memory or cookie)
- Client sends JWT in Authorization header
- Server verifies JWT on every request
🛠️ Implementing JWT Auth in Node.js (Express)
📦 Install Dependencies
npm install express auth-verify
🔑 Generate (signing) JWT on Login
const AuthVerify = require('auth-verify')
const auth = new AuthVerify({
jwtSecret: "SUPER_SECRET" // setting secret for jwt
})
// Generating jwt
auth.jwt.sign({userId: 1, user: "John Doe"}, "1h") // 1h expiration time of jwt
🔐 Login Route Example
const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
const AuthVerify = require('auth-verify')
const auth = new AuthVerify({ jwtSecret: "SUPER_SECRET" })
app.post('/login', async (req, res)=> {
const { email, password } = req.body
const user = await findUserByEmail(email)
if (!user) return res.status(401).json({ message: 'Invalid credentials' })
const isValid = await auth.crypto.verify(password, user.password)
if (!isValid) return res.status(401).json({ message: 'Invalid credentials' })
const token = await auth.jwt.sign({userId: 1, user: "John Doe"}, "1h")
res.json({ token })
})
🧱 Protecting Routes with JWT Middleware
auth.jwt.protect()
🔒 Protected Route Example
app.get('/profile', auth.jwt.protect(), (req, res)=> {
res.json({
message: 'Welcome!',
user: req.user
})
})
📤 Sending JWT from Client
Authorization: Bearer YOUR_JWT_TOKEN
⚠️ Common JWT Mistakes
- ❌ Storing JWT in localStorage (XSS risk)
- ❌ Putting sensitive data inside payload
- ❌ No token expiration
-
❌ Using weak secrets
-
✅ Use HTTP-only cookies if possible
-
✅ Always set expiresIn
-
✅ Rotate secrets in production
🧠 When Should You Use JWT?
JWT is great when:
- You have stateless APIs
- You use microservices
- You need mobile or SPA authentication
JWT is not ideal when:
- You need instant logout everywhere
- You need heavy session control
🏁 Conclusion
JWT provides a simple, scalable, and stateless way to handle authentication.
When used correctly, it’s powerful and secure.
If you’re building APIs, SPAs, or mobile apps — JWT is worth mastering.