ID token(aka JSON Web Signature (JWS)) has 3 parts separated by .
character:
Header.Payload.Signature
We can get each part by splitting the token:
parts = token.split(".")
Now I don't know the reason, but these parts do not have the base64 padding. Maybe because it is not enforced(see this)? And python base64 library requires it.
The padding character is =
, and the padding should be added to the base64 string so that it is length is multiple of 4 characters. For example if the string is 14 characters, it should have the padding ==
at the end so that it is 16 characters in total.
So the formula to calculate correct padding is this:
4 - len(base64_string) % 4
After we add the right padding and decode the string:
payload = parts[1]
padded = payload + '=' * (4 - len(payload) % 4)
base64.b64decode(padded)
what we will get is a string representation of JSON object, we can convert it to JSON with:
json.loads(base64.b64decode(padded))
Finally we can put everything in a convenience function:
import base64
import json
def parse_id_token(token: str) -> dict:
parts = token.split(".")
if len(parts) != 3:
raise Exception("Incorrect id token format")
payload = parts[1]
padded = payload + '=' * (4 - len(payload) % 4)
decoded = base64.b64decode(padded)
return json.loads(decoded)
To learn more details about id token check Takahiko Kawasaki(founder of authlete.com)'s excellent article