Amazon Cognito
Developer Guide

Verifying a JSON Web Token

These steps describe verifying a user pool JSON web token (JWT).

Prerequisites

  • This section describes tasks that might be already handled by your library, SDK, or software framework. For example, user pool token handling and management is provided on the client side through the Amazon Cognito SDKs. Likewise, the Mobile SDK for iOS and the Mobile SDK for Android automatically refresh your ID and access tokens if there is a valid (non-expired) refresh token present, and the ID and access tokens have a minimum remaining validity of 5 minutes. For information on the SDKs, and sample code for JavaScript, Android, and iOS see Amazon Cognito User Pool SDKs.

  • If you need to manually process tokens for server-side API processing, or if you are using other programming languages, there are many good libraries for decoding and verifying a JWT. See the OpenID Foundation list of libraries for working with JWT tokens.

Step 1: Confirm the Structure of the JWT

A JSON Web Token (JWT) includes three sections:

  1. Header

  2. Payload

  3. Signature

11111111111.22222222222.33333333333

They are encoded as Base64url strings, and are separated by dot "." characters. If your JWT does not conform to this structure, consider it as invalid and do not accept it.

Step 2: Validate the JWT Signature

The JWT signature is a hashed combination of the header and the payload. Amazon Cognito generates two pairs of RSA cryptograpic keys for each user pool. One of the private keys is used to sign the token.

To verify the signature of a JWT token

  1. Decode the ID token.

    1. You can use AWS Lambda to decode user pool JWTs. For more information see Decode and verify Amazon Cognito JWT tokens using Lambda.

    2. The OpenID Foundation also maintains a list of libraries for working with JWT tokens.

  2. Compare the local key ID (kid) to the public kid.

    1. Download and store the corresponding public JSON Web Key (JWK) for your user pool. It is available as part of a JSON Web Key Set (JWKS). You can locate it at https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json.

      For more information on JWK and JWK sets, see JSON Web Key (JWK).

      Note

      This is a one time step before your web APIs can process tokens. Now you can perform the following steps each time the ID token or the access token are used with your web APIs.

      This is a sample jwks.json file:

      { "keys": [{ "kid": "1234example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "1234567890", "use": "sig" }, { "kid": "5678example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "987654321", "use": "sig" }] }
      Key ID (kid)

      The kid is a hint indicating which key was used to secure the JSON web signature (JWS) of the token.

      Algorithm (alg)

      The alg header parameter represents the cryptographic algorithm used to secure the ID token. User pools use an RS256 cryptographic algorithm, which is an RSA signature with SHA-256. For more information on RSA see RSA Cryptography.

      Key Type (kty)

      The kty parameter identifies the cryptographic algorithm family used with the key, such as "RSA" in this example.

      RSA Exponent (e)

      The e parameter contains the exponent value for the RSA public key. It is represented as a Base64urlUInt-encoded value.

      RSA Modulus (n)

      The n parameter contains the modulus value for the RSA public key. It is represented as a Base64urlUInt-encoded value.

      Use (use)

      The use parameter describes the intended use of the public key. For this example, the use value sig represents signature.

    2. Search the public JSON web key for a kid that matches the kid of your JWT.

  3. Use the public key to verify the signature using your JWT library. You might need to convert the JWK to PEM format first. This example takes the JWT and JWK, and uses the Node.js library, jsonwebtoken, to verify the JWT signature:

    Node.js
    Node.js
    var jwt = require('jsonwebtoken'); var jwkToPem = require('jwk-to-pem'); var pem = jwkToPem(jwk); jwt.verify(token, pem, { algorithms: ['RS256'] }, function(err, decodedToken) { });

Step 3: Verify the Claims

To verify JWT claims

  1. Verify that the token is not expired.

  2. The audience (aud) claim should match the app client ID created in the Amazon Cognito user pool.

  3. The issuer (iss) claim should match your user pool. For example, a user pool created in the us-east-1 region will have an iss value of:

    https://cognito-idp.us-east-1.amazonaws.com/<userpoolID>.

  4. Check the token_use claim.

    • If you are only accepting the access token in your web APIs, its value must be access.

    • If you are only using the ID token, its value must be id.

    • If you are using both ID and access tokens, the token_use claim must be either id or access.

You can now trust the claims inside the token.