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 expiresnbf
(not before): when the token becomes validiat
(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.