Node.js10 min read
Authentication with JWT in Node.js
Implement JWT authentication in Node.js. Learn token generation, verification, and protected routes.
Sarah Chen
December 19, 2025
0.0k0
Authentication with JWT in Node.js
JWT (JSON Web Token) is the standard for API authentication. No sessions, stateless, scalable.
How JWT Works
1. User logs in with email/password
2. Server verifies, generates JWT
3. Server sends JWT to client
4. Client stores JWT (localStorage/cookie)
5. Client sends JWT with every request
6. Server verifies JWT, allows access
JWT Structure
header.payload.signature
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.abc123signature
Setup
npm install express jsonwebtoken bcryptjs
Generate Token
const jwt = require('jsonwebtoken');
const SECRET = process.env.JWT_SECRET || 'your-secret-key';
function generateToken(user) {
return jwt.sign(
{ userId: user.id, email: user.email },
SECRET,
{ expiresIn: '7d' }
);
}
Verify Token
function verifyToken(token) {
try {
return jwt.verify(token, SECRET);
} catch (error) {
return null;
}
}
Auth Middleware
function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'No token provided' });
}
const token = authHeader.split(' ')[1];
const decoded = verifyToken(token);
if (!decoded) {
return res.status(401).json({ error: 'Invalid token' });
}
req.user = decoded;
next();
}
Password Hashing
const bcrypt = require('bcryptjs');
// Hash password (registration)
async function hashPassword(password) {
return bcrypt.hash(password, 10);
}
// Compare password (login)
async function comparePassword(password, hash) {
return bcrypt.compare(password, hash);
}
Complete Auth Routes
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const app = express();
app.use(express.json());
const SECRET = 'your-secret-key';
const users = []; // In-memory (use database in production)
// Register
app.post('/api/register', async (req, res) => {
const { email, password } = req.body;
// Check if user exists
if (users.find(u => u.email === email)) {
return res.status(400).json({ error: 'Email already registered' });
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Create user
const user = {
id: users.length + 1,
email,
password: hashedPassword
};
users.push(user);
// Generate token
const token = jwt.sign({ userId: user.id }, SECRET, { expiresIn: '7d' });
res.status(201).json({ token, user: { id: user.id, email } });
});
// Login
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
// Find user
const user = users.find(u => u.email === email);
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// Check password
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
// Generate token
const token = jwt.sign({ userId: user.id }, SECRET, { expiresIn: '7d' });
res.json({ token, user: { id: user.id, email: user.email } });
});
// Auth middleware
function auth(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
const token = authHeader.split(' ')[1];
req.user = jwt.verify(token, SECRET);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
// Protected route
app.get('/api/profile', auth, (req, res) => {
const user = users.find(u => u.id === req.user.userId);
res.json({ id: user.id, email: user.email });
});
app.listen(3000);
Frontend Usage
// Login
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const { token } = await response.json();
localStorage.setItem('token', token);
// Authenticated request
const profile = await fetch('/api/profile', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
});
Key Takeaway
JWT enables stateless authentication. Hash passwords with bcrypt, generate tokens on login, verify tokens in middleware. Store tokens client-side, send in Authorization header. Simple and scalable!
#Node.js#JWT#Authentication#Security#Intermediate