Mikey
Mikey

Reputation: 450

AWS Cognito. How to decode JWT in Python

I want to authenticate users using Cognito Identity provider (Facebook) in Django application. When user signs-in, he is redirected to home page with access_token and id_token. These are JWT tokens. I need to decode them to get information about user. How to achieve it?

I tried using jwt library. Many resources say that I need PUBLIC_KEY converted to PEM format to decode these tokens. I visited: https://cognito-idp.{aws-region}.amazonaws.com/{user-pool-id}/.well-known/jwks.json and got dictionary:

{
  "keys": [
    {
      "alg": "RS256",
      "e": "AQAB",
      "kid": "cKgEILaVv5nXrJNBtfdaEVfA9Sn+GNdMpXbO58Li+eLyiA=",
      "kty": "RSA",
      "n": "kpE2A8GfBoDiLcnHme9WLSIMezPAXg8ibZ8hIa4GvmJAT1LmR9CDN0Yt-JlKE_gH73HbldpgqCbflygbcZtdn1RMdfafdafaQq3sOY0RJqC8-jdZTWb0Cbw2E-fmmOtgHqz11ZlbqaZYpcRYvyNwuWQs05kikzaUudwp05TTd4N0VznbMMm9peu_Ghw7nqlgkvU8WWO6tD_LzF8VDTroKdGAnrh3kwRVY8le5JwzoGMDVbNtOQFwla8yyxNfRRFQVkcnOxb14BhrO3N8ZsI-E9eB9ZbUNt27DxAMjxsNzERSUx3gm7zq-d2SYyZ31P_FNxOTS0RlKPN69Jlscack7ghM_nZdnw",
      "use": "sig"
    },
    {
      "alg": "RS256",
      "e": "AQAB",
      "kid": "wMYp8SsLhXBtE2wbYK1hQfdafadfadeiYkDYXctg1GkdmTTFs+I=",
      "kty": "RSA",
      "n": "i_W1pexAB1FhY3oJ0jEGeks1b8jCFZOWU7PAvzi3kdeP7JR2IP91W8FV9ou6gT1dn6F8ZbDvJEF9PNJkmQxwvHkoeYzgaOhNFXBU5Jfv20rQfdafa56PufchgtGndaI22TnnPDg_L5UElaljJvmzTcDTk0xHqJRxhw2LAqembfij5TV_8mSHpqIbWvppOTqT7s3zI7DdfDLDOX7CHFRht3uesX5drVo-S9IsJCJ2l3rCChTCy8e32YY68iHH40t5vVPkuqr1ffMfKYkyXC3urliCawRKnrk62ngAskjRiAihmIl8E79_Ddfn5O5RYqLY71Q4T6Epep4C1ygjlBrToFd8Haw",
      "use": "sig"
    }
  ]
}

I don't know what to grab from here.

Upvotes: 7

Views: 11499

Answers (2)

FaeTheWolf
FaeTheWolf

Reputation: 79

Using the PyJWT library, you can decode a JWT token via:

import jwt

encoded = token  # replace this with your encoded token
jwt.decode(encoded, algorithms=["RS256"], options={"verify_signature": False})

The options configuration will tell the PyJWT library to ignore the public-key aspect of the verification process, and decode the Base64 key regardless.

note – the algorithm is hardcoded as RS256, per the AWS Cognito standard, but you can choose to leave that argument out if you wish (PyJWT will figure it out).


To decode and verify the JWT, you can utilize the borisrozumnuk/cognitojwt library:

from cognitojwt import jwt_sync

jwt_sync.decode(token)

EDIT: per comment from @Samuel, the aws-support-tools library (below) actually relies on an unmaintained 3rd party library with known vulnerabilities, and SHOULD NOT BE USED.

If you want to avoid 3rd-party libraries, you manually install the AWSLabs aws-support-tools 'decode-verify-jwt' module:

from decode-verify-jwt import lambda_handler as decode_verify_jwt

decode_verify_jwt({'token': token}, None)

Upvotes: 6

Shashidhar Kudari
Shashidhar Kudari

Reputation: 601

The answer given above is outdated so adding the new code if your are using jwt for decoding it

from jwt import JWT
from jwt.exceptions import JWTDecodeError

def decode_token(token:str):
   try:
      jwt_ = JWT()
      return jwt_.decode(token, algorithms=['RS256'],do_verify=False)
   except JWTDecodeError as e:
      print('token expired')

Upvotes: -1

Related Questions