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.
from jose import jws
signed = jws.sign({'a': 'b'}, 'secret', algorithm='HS256')
jws.verify(signed, 'secret', algorithms='HS256')
# the verify only returns the payload
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.
from jose import jwe
encrypted = jwe.encrypt('Hello, World!', 'asecret128bitkey', algorithm='dir', encryption='A128GCM')
jwe.decrypt(encrypted, 'asecret128bitkey')
# => 'Hello, World!'
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.
from jose import jwt
encoded = jwt.encode({'a': 'b'}, 'secret', algorithm='HS256')
jwt.decode(encoded, 'secret', algorithms='HS256')
# => {'a': 'b'}
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:
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