Skip to main content

How to validate JWT

Validating a JSON Web Token (JWT) involves verifying the signature. It should belong to the correct public Key which will ensure the authenticity of the information. Also it must not be expired and must be sent to the correct recipients.

What is the difference between Access and ID Token

When your authenticaiton Challenge is successful you will get two Tokens. The first one is an Access Token, and the second is an ID Token.

The Access Token decorates the request from the front end to the back end. It provides access to server-side user resources for each browser request. The Access Token can be seen as the Key to the door.

On the other hand, the ID Token provides the identity part of authentication, it proves that the user is who they say they are.

These Tokens can be decrypted using online tools like JWT.io or using libraries specific to each language. However, decoding is quite simple since it can be done using a simple Base64 Decode.

Now that you have seen this you may be wondering how can we ensure that the Token is not a Token altered by a malicious person? All you need to do is verify your signature. Indeed, JWT Tokens have a signature mechanism. Each Token is signed by Cryptr when issued via a private Key. For your part, you can easily find your public Key using the information contained in the decrypted Cryptr Token. Once your public Key has been retrieved, you can then verify the signature of your Token. This is what we will see in more detail in this guide.

  1. Retrieve User Tokens
  2. Get the Token you need
  3. Decode the Token
  4. Retrieve the public Key
  5. Verify Signature

1. Retrieve User Tokens

To start you will have to retrieve your User's Tokens. Most of the time after an Authentication Challenge you will receive a code via the HTTP request parameters (from our service to your redirection URL).

{your-redirection-url}?code=9xO5oCjbwHHeIPu8QId3325AAmGjZ76vjD5WA49…&request_id=1cc788ee-c8df-4a1f-bc45-d7301e7591f9

By using this code you will be able to retrieve all the information you need (ID Token, Access Token, Expiration, etc.). To do this you need to make an API request to our services using this code as a parameter as well as specifying the grant_type “authorization_code”.

For example the query would look like:

We first need to get the Key ID (kid) of the JWT to find the associated public Key. You can get the kid from the Token header (the first part before the first dot) with a simple base64 decode.

curl -X POST '${cryptr_service_url}/oauth/token' \
-d grant_type="authorization_code" \
-d code="9xO5oCjbwHHeIPu8QId3325AAmGjZ76vjD5WA49…"

You should then receive a payload containing what you need next.

2. Retrieve the Token you need

You should now be faced with a payload similar to this:

{
"access_token": "eyJhbGciO…",
"expires_in": 36000,
"id_token": "eyJhbGciO…",
"scope": [
"openid",
"email",
"profile"
],
"token_type": "Bearer"
}

Depending on your needs, you can then retrieve either the Access Token, the ID Token or both. As it stands, it is of little use to you since it is encoded and therefore impossible for a human to understand. So you will have to decode it.

3. Decode the token

Once your token has been recovered, you must decode it to be able to access the information it contains in a readable manner. Most languages ​​have libraries or native functions that will allow this token to be decrypted, which we remind you is in JWT format.

Here is one way to do it in pseudo-code:

function decodeJWT(token):
parts = token.split('.')
if length(parts) != 3:
return "Invalid JWT format"

header = base64Decode(parts[0])
payload = base64Decode(parts[1])

try:
header_json = parseJson(header)
payload_json = parseJson(payload)
except:
return "Invalid JWT content"

return header_json, payload_json

4. Retrieve the public key

Once you have decoded your Token you should have a header similar to this:

{
"alg": "RS256",
"iss": "https://auth.cryptr.dev/t/muffun-qy6S9EYuXgtcTeG3YiYwX4",
"kid": "cbf227bd-1427-44f0-8581-20199f0a8ebb",
"typ":"JWT"
}

and a payload similar to:

{
"aud": [],
"client_id": "d1f1fc75-51a3-4c07-8ba6-698521728290",
"email": "alexandre@cryptr.co",
"env": "sandbox",
"exp": 1709330437,
"iat": 1709294437,
"jti": "0c46d26c-9974-4ee4-96d3-081990e643f9",
"jtt": "access",
"org": "muffun-qy6S9EYuXgtcTeG3YiYwX4",
"scope": ["openid", "email", "profile"],
"sub": "cryptr|41a55520-645d-49eb-a0e8-2e95fde8f56c",
"ver": 3
}

To retrieve your public key you will be able to use the kid contained in the header of your JWT. Once your kid has been retrieved you will have to use the following endpoint:

{your-cryptr-service-url}/t/{your_org_domain}/.well-known

To make it simpler, you can also simply retrieve the ISS contained in the header of your token and add the /.well-known route.

Caution

If you prefer this method always check that the domain is https://{your-domain}.authent.me for dedicated instance or https://cryptr.eu (can also be .us or .asia)

5. Verify the signature

On this .well-known endpoint you can retrieve the public key corresponding to your kid. Once the public key (also called JWK) has been found, simply retrieve it and in most cases use it as is (in full) in JWT libraries to verify the signature of your Access / ID Token. Some libraries also accept passing the well-known URL directly. Be careful to check the specifics of each library for your language.

Depending on the library used, you may have to check the correspondence of your signature yourself. If this is the case, you will simply have to compare the signature contained in your JWT with the one you obtained. If the two character strings are identical, congratulations, you have just proven the authenticity of your JWT.

I can trust the presence of the Token information, so I can validate:

  • temporality
  • exhalation,
  • the issuer: it comes from my Cryptr authorization service
  • and that as an application I am the right recipient (client_id), the right audience

To conclude here is some tips about how to use your Tokens.

User identity:

  • in browser the id_token must be the only way to authenticate an user
  • on the server side, the user_info from an access_token, should be used because we never send the id_token in Client / Server exchanges

We hope that this short guide has helped you better understand JWTs and above all that it has helped you to decode, use and verify the authenticity of the tokens that we send you.