JSON Web Token (JWT) Authorization for Python's Requests

JSON Web Tokens are “a compact URL-safe means of representing claims to be transferred between two parties.” The “claims” are assertions about what’s going on, and they’re cryptographically signed, either with a shared secret between client and server or using public key cryptography.

One place they’re being used is in Mozilla’s BadgeKit API. There, clients of the API have a shared secret with the server. That secret is used to sign a statement of the HTTP path, method, and request body (for POST and PUT requests). Assuming nothing important happens in the other HTTP headers, this means that an evesdropper can only replay the exact HTTP request that the real client made. This makes it better than simply including unchanging credentials, because once the credentials are sniffed from the network, they can be reused to make any request to the server.

Unfortunately, JSON Web Tokens are fiddly to assemble. There is a good implementation for Python called PyJWT (PyPI). However, to use it with Kenneth Reitz’s immortal work, requests, one must write a custom authentication plugin. Well, I’ve done that! Yay! The code is on GitHub, and on PyPI as requests-jwt. The documentation is on Read the Docs.

import requests
from requests_jwt import JWTAuth, payload_method

auth = JWTAuth('superSekr3t')
# ... other claims/payloads
resp = requests.get('http://auth-required.example.com/', auth=auth)

This is part of my current work with Dr. Daniel Hickey, bringing digital badges (which are more interesting than they sound) to online courses hosted with Open edX.