BlogJWT Token Expiration Best Practices
·3 min read·JWTSecrets Team

JWT Token Expiration Best Practices

Learn the best practices for managing JWT expiration, including how to use the 'exp' claim, implement refresh tokens, and optimize token lifetime for secure APIs.

Managing JSON Web Token (JWT) expiration is a critical aspect of API security. A common mistake developers make is issuing long-lived tokens, which increase the blast radius of a potential token leakage. By implementing strict JWT expiration best practices, you minimize the risk and ensure your API remains resilient.

The Role of the 'exp' Claim

The fundamental mechanism for controlling how long a JWT is valid is the exp (expiration time) claim defined in RFC 7519. This claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. Your application logic must perform this check during every request. Validation is not automatic; you must explicitly verify that the current time is before the time specified in this claim.

Node.js Example: Validating 'exp'

const jwt = require('jsonwebtoken');

function validateToken(token, secret) {
  try {
    const decoded = jwt.verify(token, secret);
    if (Date.now() >= decoded.exp * 1000) {
        return { valid: false, error: 'Token expired' };
    }
    return { valid: true, payload: decoded };
  } catch (err) {
    return { valid: false, error: err.message };
  }
}

Python Example: Validating 'exp'

import jwt
import time

def validate_token(token, secret):
    try:
        payload = jwt.decode(token, secret, algorithms=['HS256'])
        if time.time() >= payload['exp']:
            return {'valid': False, 'error': 'Token expired'}
        return {'valid': True, 'payload': payload}
    except jwt.ExpiredSignatureError:
        return {'valid': False, 'error': 'Token expired'}
    except Exception as e:
        return {'valid': False, 'error': str(e)}

Optimizing JWT Lifetime

To maintain a high security posture, keep your access token lifetime short. A window of 5 to 15 minutes is typical for most web applications. Short-lived access tokens ensure that if an attacker manages to exfiltrate a token, their access will be automatically terminated shortly thereafter. If you find your users complaining about frequent logouts, do not simply increase the token lifetime. Instead, implement a proper refresh token rotation strategy.

Why Refresh Tokens Matter

When your access token expires, your application should not force the user to re-authenticate. Instead, use a JWT refresh token. This token is a longer-lived credential that the client uses to request a new access token from the authorization server.

Best practices for refresh tokens include:

  • One-time use: Invalidate the refresh token as soon as it is used.
  • Refresh Token Rotation: Issue a brand-new refresh token every time the client requests a new access token, effectively invalidating the previous one.
  • Secure Storage: Because of their longer lifetime, refresh tokens must be stored in secure environments (e.g., HTTP-only, SameSite cookies for web apps) to prevent cross-site scripting (XSS) attacks.

Validate Tokens Continuously

Validation is not just for the exp claim. You must verify the signature against a trusted public key, check that the issuer (iss) matches your trusted identity provider, and ensure the intended audience (aud) matches your API name. You can use our free JWT Validator to test and debug your token claims to ensure everything is configured correctly.

Conclusion

Effective management of JWT lifetime is a balancing act between user experience and security. Prioritize creating a robust token lifecycle that favors short-lived access tokens paired with secure refresh token handling. If you are ever unsure about your current token configuration, verifying your tokens with a reliable utility is the first step toward a more secure architecture. For more on securing the underlying secrets that sign these tokens, check out our guide on what is a JWT secret key and why it matters.