In this article, I will show you how to verify and decode the Cognito JWT Tokens token. Before going ahead, we should understand quickly: What is JWT and what does it have?
JSON Web Token (JWT) is an open standard used to share security information between two parties — a client and a server.
JWT has 3 parts: Header, Payload, and Signature.
This token is safe and reliable because the signature that identifies the token generated by Cognito is not from a 3rd party. We use the public key provided by Cognito to verify the token. So there is no way to spoof the signature. It is possible to forge signatures, even stolen credentials, but they cannot forge signatures from Cognito.
To get the public key we can have 2 ways using a web browser or Postman in the URL format below:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json
After you send the request, you will get the result as below:
Postman
Web browser
In the results above we see that there are 2 public keys, do you ask the question which public key do we use? So how do we know which key we will use?
First, go to the page JWT
Then you paste your id-token in
After decoding you will see a kid. Find the kid in the public key that matches the kid after deciding. You will use that public key.
Please create a jwks.json file with the required public key content.
First, you need to install the following 2 packages
jsonwebtoken jwk-to-pem
Next, create a file to verify the token with the name is verify-token.ts
import { NextFunction, Request, Response } from 'express'; import { readFileSync } from 'fs'; import jwt from 'jsonwebtoken'; import jwkToPem from 'jwk-to-pem'; import path from 'path'; const verifyIdToken = async (req: Request, res: Response, next: NextFunction) => { try { const data = readFileSync(path.resolve(__dirname, 'jwks.json')) as any; const authorization = req.headers?.['authorization'] as string; if (!authorization) { return new BadRequestResponse('Missing token.').send(res); } const token = authorization.split(' ')[1]; const pem = jwkToPem(JSON.parse(data)); const auth = jwt.verify(token, pem, { algorithms: ['RS256'] }); res.locals.auth = auth; return next(); } catch (error: any) { return next(new BadTokenError(error.message)); } };
Results when verifying successfully
{ sub: 'a1f715a3-c758-443a-93ea-9939e4354b6e', iss: '', phone_number_verified: true, 'cognito:username': '', origin_jti: '0698df1d-5687-46cf-a4ac-d964ed3cc629', aud: '', event_id: 'cf9115a3-0d8a-43c6-82f9-f2e7f6ef2853', token_use: 'id', auth_time: 1671875444, phone_number: '', exp: 1671879043, iat: 1671875444, jti: 'b453e27e-2086-45f0-bd3d-35542ab4e0cb' }
Hope this article will be of help to you. Good luck!