How toValidate exp, iat, and nbf in JWTs

When using JWTs as access tokens in OAuth2, it's important to verify when the token is valid—and when it isn’t.

There are three standard claims used to control token timing:

  • exp (expiration): when the token expires
  • nbf (not before): when the token becomes valid
  • iat (issued at): when the token was created

Verifying exp with @edgefirst-dev/jwt

When using the JWT.verify() method from @edgefirst-dev/jwt, the library automatically checks the exp claim:

const token = await JWT.verify(accessToken, jwks, {
  issuer: "https://example.com",
  audience: "https://api.example.com",
});

If the token has expired, this method will throw.

Manually validating nbf and iat

The nbf (not before) and iat (issued at) claims are not automatically validated, but you can easily add your own checks:

if (token.nbf && Date.now() / 1000 < token.nbf) {
  throw new Error("Token not yet valid");
}

if (token.iat && Date.now() / 1000 < token.iat) {
  throw new Error("Token issued in the future");
}

Note: the comparison uses Date.now() / 1000 because JWT timestamps are in seconds, not milliseconds.

Validating these claims helps you avoid accepting tokens that are expired, not yet valid, or potentially forged with an invalid iat.

It’s a small step that improves your API’s security and predictability.


Want to master secure OAuth2 flows in React Router apps?

📘 My book React Router OAuth2 Handbook is now available!

It covers everything from the basics to advanced topics like PKCE, refresh tokens, and E2E auth testing.

books.sergiodxa.com/release