JAVASCRIPT

Implementing JWT Refresh Token Mechanism for Enhanced Security

Boost JWT security by integrating a refresh token mechanism, issuing short-lived access tokens and securely renewing them to minimize exposure and unauthorized access.

const express = require('express');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');

const app = express();
app.use(express.json());

const ACCESS_TOKEN_SECRET = crypto.randomBytes(64).toString('hex');
const REFRESH_TOKEN_SECRET = crypto.randomBytes(64).toString('hex');

// In-memory store for refresh tokens. In production, use a persistent store (e.g., database, Redis)
let refreshTokens = [];

function generateAccessToken(user) {
  return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '15m' }); // Short-lived access token
}

function generateRefreshToken(user) {
  const refreshToken = jwt.sign(user, REFRESH_TOKEN_SECRET, { expiresIn: '7d' }); // Long-lived refresh token
  refreshTokens.push(refreshToken); // Store the refresh token
  return refreshToken;
}

app.post('/login', (req, res) => {
  // Authenticate user (e.g., check username/password against DB)
  const user = { id: 1, username: 'john_doe' }; // Dummy user

  const accessToken = generateAccessToken(user);
  const refreshToken = generateRefreshToken(user);
  res.json({ accessToken, refreshToken });
});

app.post('/token', (req, res) => {
  const { refreshToken } = req.body;

  if (!refreshToken) return res.sendStatus(401); // No refresh token provided
  if (!refreshTokens.includes(refreshToken)) return res.sendStatus(403); // Invalid refresh token

  jwt.verify(refreshToken, REFRESH_TOKEN_SECRET, (err, user) => {
    if (err) return res.sendStatus(403); // Refresh token expired or invalid

    // Remove 'iat' (issued at) and 'exp' (expiration) from user object before generating new token
    const newAccessToken = generateAccessToken({ id: user.id, username: user.username });
    res.json({ accessToken: newAccessToken });
  });
});

app.delete('/logout', (req, res) => {
  const { refreshToken } = req.body;
  refreshTokens = refreshTokens.filter(token => token !== refreshToken);
  res.sendStatus(204); // Successfully logged out
});

app.listen(3002, () => {
  console.log('JWT Refresh Token Server running on port 3002');
});
How it works: JSON Web Tokens (JWTs) are commonly used for authentication. To enhance their security, especially against token theft, a refresh token mechanism is often implemented. This snippet illustrates how to use short-lived access tokens (e.g., 15 minutes) for API access and long-lived refresh tokens (e.g., 7 days) to obtain new access tokens. If an access token is compromised, its short lifespan limits exposure. Refresh tokens, stored securely (e.g., in a database), are used to re-authenticate and issue new access tokens without requiring the user to re-enter credentials, providing a balance between security and user experience. Logout involves revoking the refresh token.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs