How toValidate JWTs with JWKS
When using JWTs as access tokens in OAuth2, one of the most important things you need to do is validate their signature. This ensures the token was actually issued by a trusted Authorization Server and hasn't been tampered with.
But how do you verify the signature without knowing the exact public key?
That's where JWKS comes in.
What is a JWKS?
JWKS stands for JSON Web Key Set. It’s a standard endpoint where the Authorization Server exposes its public keys. These keys are used to verify the signature of JWTs issued by that server.
The JWKS is usually found at a well-known URL like:
https://auth.example.com/.well-known/jwks.json
This JSON document contains one or more public keys. Each JWT issued by the server includes a kid
(key ID) in its header, so your app can pick the right key from the set.
Verifying a JWT using JWKS
To verify a JWT using the JWKS, you first fetch the key set from the server, then use it to validate the token. Here's how to do it using @edgefirst-dev/jwt
:
import { JWK, JWT } from "@edgefirst-dev/jwt";
const jwks = await JWK.importRemote(
new URL("https://example.com/.well-known/jwks.json")
);
const token = await JWT.verify(accessToken, jwks);
Now that the token is verified, you can safely access its claims:
token.subject; // the user ID
token.scope; // list of granted scopes
token.exp; // expiration timestamp
Why use JWKS?
JWKS allows your API to verify JWTs locally, without calling the Authorization Server on every request. This means:
- ✅ No network latency or failure risks
- ✅ Stateless and cache-friendly
- ✅ Ideal for distributed or high-traffic systems
You still need to validate things like issuer
, audience
, and expiration
, but the signature validation is fast and reliable thanks to JWKS.
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