3

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.

Mikey
  • 400
  • 4
  • 11
  • 2
    you don't need any key to DECODE a JWT. A JWT consists of 3 base64url encoded parts, header, payload and signature. You can just decode the payload with any base64url decoder. You would need the public key only to VERIFY the signature. Try to decode your token on http://jwt.io – jps Apr 16 '19 at 07:58
  • I guess this is your solution? https://stackoverflow.com/questions/38119621/where-can-i-find-the-secret-key-for-the-jwt-from-cognito – nologin Apr 16 '19 at 08:09
  • @jps Can you help me. I encountered another problem: ``` from base64 import b64decode header, payload, signauture = id_token.split(".") payload_string = b64decode(payload) ``` I'm getting Incorrect Padding Error. If I put the id_token on jwt.io I'm able to see my credentials, so it's not id_token fault. Thanks in advance. – Mikey Apr 17 '19 at 06:44
  • 1
    maybe that helps: https://stackoverflow.com/questions/6102311/python-b64decode-incorrect-padding – jps Apr 17 '19 at 07:14
  • I used pyjwkest library instead of base64, and decoded payload without a problem. Thanks once again for helping. – Mikey Apr 17 '19 at 07:58

1 Answers1

4

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)

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)
FaeTheWolf
  • 41
  • 4