JWT Primer - loum/jwt-auth GitHub Wiki
JWTs are an Internet Engineering Task Force (IETF) standard. A detailed description can be found in the Internet-draft. However, the basics will be discussed here including how to generate a token using the Python standard library.
Note: In general, it is better to use third-party libraries to abstract the creation of JWTs such as PyJWT and Django REST frameworkhe
A typical JWT is shown here:
eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpX
VCJ9.eyJ1c2VyX2lkIjogMX0.g4AmZqzBhVs
FzGjIP39VwouQXvH5mhv2zR8pUJvjS6w
On face value, a JWT is just a base-64 encoded string made up of three parts:
- header - which defines algorithm we will be using to sign the token
- payload - data to encode as a token
- signature
Each part is separated by periods .
and the trailing equal signs =
are omitted.
Header
A JWT header is a JSON string construct with 2 keys:
{"alg": "HS256", "typ": "JWT"}
Here, the typ
key indicates that this object is a JWT and the alg
key indicates the algorithm to use for the signature.
Note: HS256
represents the Hash-based Message Authentication Codes (HMACs) using SHA-256. This is the current encryption mechanism used by CDCi
The header can be generated with the following Python code:
>>> import json
>>> import hmac
>>> import hashlib
>>> import base64
>>>
>>> segments = []
>>>
>>> header_dict = {
... 'typ': 'JWT',
... 'alg': 'HS256'
... }
>>>
>>> json_header = json.dumps(header_dict)
>>>
>>> header = base64.urlsafe_b64encode(json_header).rstrip('=')
>>> segments.append(header)
>>> header
'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9'
Payload
The payload (also referred to as the claim) represents the data. The following example payload feature a single key user_id
:
>>> payload_dict = {
... 'user_id': 1
... }
>>>
>>> json_payload = json.dumps(payload_dict)
>>> payload = base64.urlsafe_b64encode(json_payload).rstrip('=')
>>> segments.append(payload)
>>> payload
'eyJ1c2VyX2lkIjogMX0'
Signature
Here, the payload encoding/decoded will be based on a shared key, SECRET
:
>>> SECRET = 'abc123'
>>> signing_input = '.'.join(segments)
>>> sig = hmac.new(SECRET, signing_input, hashlib.sha256)
>>> signature = base64.urlsafe_b64encode(sig.digest()).rstrip('=')
>>> segments.append(signature)
>>>
>>> signature
'g4AmZqzBhVsFzGjIP39VwouQXvH5mhv2zR8pUJvjS6w'
>>> token = '.'.join(segments)
Other encryptions mechanisms such as digitally signatures are also supported.
Python JWT Tools
The PyJWT project attempts to abstract much of the ceremony around JWT encoding and decoding. The above can also be achieved with the following JWT command:
>>> import jwt
>>> encoded = jwt.encode({'user_id': 1}, 'abc123', algorithm='HS256')