Migrating from python-jose

python-jose supports all JOSE specifications, similar to joserfc. However, there are significant differences in code structure, method names, and parameter usage. Additionally, joserfc offers built-in Python type hints, enhancing code readability and type safety.

Another key difference is that python-jose only supports compact serialization and deserialization, whereas joserfc supports both compact and JSON serialization formats, offering greater flexibility in handling JOSE data.

JWS

In python-jose, the methods used for serialization and deserialization are jws.sign and jws.verify, respectively.

On the other hand, joserfc uses jws.serialize_compact for serialization and jws.deserialize_compact for deserialization.

python-jose
from jose import jws

signed = jws.sign({'a': 'b'}, 'secret', algorithm='HS256')
jws.verify(signed, 'secret', algorithms='HS256')
# the verify only returns the payload
joserfc
import json
from joserfc import jws
from joserfc.jwk import OctKey

key = OctKey.import_key("secret")
protected = {"alg": "HS256"}
signed = jws.serialize_compact(protected, json.dumps({'a': 'b'}), key)
obj = jws.deserialize_compact(text, key)
# access the payload with obj.payload

Important

joserfc is designed to be highly explicit, requiring the use of specific key types, payload formats, and other components. For example, in the previous example, we explicitly use an OctKey instead of a simple string. Additionally, since JWS in joserfc only supports encoding strings and bytes, you cannot pass a dictionary directly as the payload. Instead, the payload must first be converted to a JSON string using json.dumps. This explicit approach ensures better type safety and clarity in your code.

JWE

In python-jose, the methods used for encryption and decryption are jwe.encrypt and jwe.decrypt. However, since joserfc supports both compact and JSON serialization formats, it provides distinct methods: jwe.encrypt_compact and jwe.decrypt_compact for compact serialization, ensuring clear differentiation between the formats and greater flexibility in handling JWE operations.

python-jose
from jose import jwe

encrypted = jwe.encrypt('Hello, World!', 'asecret128bitkey', algorithm='dir', encryption='A128GCM')
jwe.decrypt(encrypted, 'asecret128bitkey')
# => 'Hello, World!'
joserfc
from joserfc import jwe
from joserfc.jwk import OctKey

key = OctKey.generate_key(128)  # 128bit key
protected = {'alg': 'dir', 'enc': 'A128GCM'}
encrypted = jwe.encrypt_compact(protected, 'Hello, World!', key)
obj = jwe.decrypt_compact(encrypted, key)
# obj.payload => b'Hello, World!'

JWT

The jwt module in python-jose supports only JWS (JSON Web Signature) mode, whereas joserfc provides support for both JWS and JWE (JSON Web Encryption) modes. Although both libraries utilize the encode and decode methods, their parameters differ significantly in terms of structure and flexibility.

python-jose
from jose import jwt

encoded = jwt.encode({'a': 'b'}, 'secret', algorithm='HS256')
jwt.decode(encoded, 'secret', algorithms='HS256')
# => {'a': 'b'}
joserfc
from joserfc import jwt
from joserfc.jwk import OctKey

key = OctKey.import_key("secret")
# jwt.encode(header, payload, key)
encoded = jwt.encode({"alg": "HS256"}, {'a': 'b'}, key)
token = jwt.decode(encoded, key)
# => token.header : {"alg": "HS256"}
# => token.claims : {"some": "payload"}

get_unverified_header

The jwt module in python-jose provides a method called get_unverified_header, which allows extracting the header from a JWT without verifying its signature.

In joserfc, we can get the unverified header with:

joserfc
from typing import Any
from joserfc import jws

def get_unverified_header(token: str) -> dict[str, Any]:
    token_content = jws.extract_compact(token.encode())
    return token_content.protected

JWK