7👍
Know this is an old post but I found it via Google so I thought somebody else might drop in…
I ended up doing:
segments = response['id_token'].split('.')
if (len(segments) != 3):
raise Exception('Wrong number of segments in token: %s' % id_token)
b64string = segments[1]
b64string = b64string.encode('ascii')
padded = b64string + '=' * (4 - len(b64string) % 4)
padded = base64.urlsafe_b64decode(padded)
3👍
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
- [Django]-“select_for_update” called inside an atomic block still TransactionManagementError
- [Django]-Django objects change model field
- [Django]-Django inline – allow adding disable editing
- [Django]-Override delete_selected() and update fields of child model
1👍
Well, I figured out why…
I used base64.b46decode(id_token) to decode it.
However, I should split id_token by ‘.’ and decode them separately.
So I can get header, claims and signature from id_token.
I was just too stupid for ignoring those little ‘.’ in the string….
- [Django]-Please suggest some alternative to Drupal
- [Django]-How to use django-select2 widgets in django admin site?
- [Django]-Missing mysql.sock; yielding OperationalError: (2002, "Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)")
- [Django]-Adding days to a date via the ORM