SyntaxStudy
Sign Up
Express.js JWT Authentication with jsonwebtoken
Express.js Beginner 1 min read

JWT Authentication with jsonwebtoken

JSON Web Tokens (JWTs) are the standard mechanism for stateless authentication in Express REST APIs. After a successful login, the server signs a token containing the user's ID and role using a secret key and returns it to the client. Subsequent requests include the token in the `Authorization: Bearer ` header. The server verifies the signature on each request without consulting a session store. The `jsonwebtoken` package provides `jwt.sign()` to create tokens and `jwt.verify()` to validate and decode them. Always set an expiry (`expiresIn`) to limit the window of exposure if a token is stolen. Short-lived access tokens (15 minutes) paired with longer-lived refresh tokens (7 days) give a good security/usability balance. Store the JWT secret in an environment variable and rotate it periodically. Never log the full token. For multi-server deployments, all instances share the same secret (or use asymmetric RS256 keys where only the auth server holds the private key). HTTPS is mandatory — JWTs provide integrity but not confidentiality.
Example
// npm install jsonwebtoken bcryptjs
const express  = require('express');
const jwt      = require('jsonwebtoken');
const bcrypt   = require('bcryptjs');
const router   = express.Router();

const JWT_SECRET  = process.env.JWT_SECRET || 'change_me';
const JWT_EXPIRES = '15m';

// Fake user store (use a real DB in production)
const users = [
    { id: 1, email: 'alice@example.com',
      hash: bcrypt.hashSync('Password1!', 10) },
];

// POST /auth/login
router.post('/login', async (req, res) => {
    const { email, password } = req.body;
    const user = users.find(u => u.email === email);
    if (!user || !bcrypt.compareSync(password, user.hash)) {
        return res.status(401).json({ error: 'Invalid credentials' });
    }
    const token = jwt.sign(
        { sub: user.id, email: user.email },
        JWT_SECRET,
        { expiresIn: JWT_EXPIRES, algorithm: 'HS256' }
    );
    res.json({ token, expiresIn: JWT_EXPIRES });
});

// Auth middleware
function authenticate(req, res, next) {
    const auth = req.headers.authorization || '';
    const [, token] = auth.split(' ');
    try {
        req.user = jwt.verify(token, JWT_SECRET);
        next();
    } catch {
        res.status(401).json({ error: 'Invalid or expired token' });
    }
}

// Protected route
router.get('/profile', authenticate, (req, res) => {
    res.json({ userId: req.user.sub, email: req.user.email });
});

module.exports = router;