DEV Community

Kamil
Kamil

Posted on • Originally published at banach.net.pl on

Reading JWT token claims without a library

Almost everybody who works on web apps knows what JWT (JSON Web Token) is. They become pretty popular and are now widely used.

Without going into details (which can be read e.g. at jwt.io/introduction) JWT is built from three parts divided by dots:

header.payload.signature
Enter fullscreen mode Exit fullscreen mode

The middle part, payload, is interesting for us. It contains claims, which are statements about an entity (e.g. the user) and some additional data.

For purpose of this post we will use an example token from jwt.io (click on the link to open it in the debugger!) which looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Enter fullscreen mode Exit fullscreen mode

The payload in the token is just a base64 encoded JSON object. That means we can decode it and load this JSON string into the dictionary to have easy access to properties.

There is only one tricky part here - base64 padding! The payload in the JWT is alfa-numeric only, there is no = character. To be sure that it will be decoded properly we need to add max padding (==) to the payload string - it will be ignored if not needed. But if we will not have it there (but it is expected to be) - decoder will throw an error.

To sum up all above stuff in simple lines of code in Python:

import base64
import json
# Assuming the token is in the token variable 
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." \
"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ." \
"SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
# Split by dot and get middle, payload, part;
token_payload = token.split(".")[1]
# Payload is base64 encoded, let's decode it to plain string
# To make sure decoding will always work - we're adding max padding ("==")
# to payload - it will be ignored if not needed.
token_payload_decoded = str(base64.b64decode(token_payload + "=="), "utf-8")
# Payload is JSON - we can load it to dict for easy access
payload = json.loads(token_payload_decoded)
# And now we can access its' elements - e.g. name
name = payload["name"]
# Let's print it - it should show "John Doe"
print(name)

Enter fullscreen mode Exit fullscreen mode

You can run it in the browser on Replit (Reading JWT token without library on Replit) or locally with Python 3.

And that’s all. It is pretty simple, isn’t it?

And it feels great to be able to do it without any additional tools! :-)

Top comments (1)

Collapse
 
glebsvechnikov profile image
Gleb Svechnikov

Yes, that how I've done it in previous project. Complexity is on server side, backend needs to parse token, check validity, check permissions before returning response to client. On client side if you store JWT in cookies, there is a limit for its length. But apart from it no problems.