JSON Web Tokens are the standard for API authentication in 2026. Day 1 covers how JWTs work, how to implement them correctly, and the common mistakes that lead to security vulnerabilities.
A JWT is a signed token containing claims (user ID, email, roles). The server creates it on login and the client sends it with every request. The server verifies the signature — no database lookup required.
# A JWT looks like:
# eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTcwMH0.abc123
# Three parts, base64-encoded and separated by dots:
# HEADER.PAYLOAD.SIGNATURE
# Header: {"alg": "HS256", "typ": "JWT"}
# Payload: {"userId": 1, "exp": 1700000000}
# Signature: HMAC-SHA256(header + "." + payload, SECRET_KEY)npm install jsonwebtoken bcrypt expressconst jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const JWT_SECRET = process.env.JWT_SECRET; // Long random string
const JWT_EXPIRY = '15m'; // Short-lived access tokens
// Login endpoint
app.post('/login', async (req, res) => {
const { email, password } = req.body;
// Look up user
const user = await User.findByEmail(email);
if (!user) return res.status(401).json({ error: 'Invalid credentials' });
// Verify password (bcrypt compares hash)
const valid = await bcrypt.compare(password, user.passwordHash);
if (!valid) return res.status(401).json({ error: 'Invalid credentials' });
// Issue JWT
const token = jwt.sign(
{ userId: user.id, email: user.email, role: user.role },
JWT_SECRET,
{ expiresIn: JWT_EXPIRY }
);
res.json({ token });
});
// Authentication middleware
function requireAuth(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'No token provided' });
}
const token = authHeader.slice(7);
try {
const decoded = jwt.verify(token, JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(401).json({ error: 'Token expired' });
}
return res.status(401).json({ error: 'Invalid token' });
}
}
// Protected route
app.get('/profile', requireAuth, (req, res) => {
res.json({ user: req.user });
});