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.
I'm currently writing a book called React Router OAuth2 Handbook, focused on implementing secure OAuth2 authentication in Remix and React Router apps—using patterns you can apply to any web app.
The landing page is live (book coming soon) at books.sergiodxa.com.