File: python-jose.rst

package info (click to toggle)
joserfc 1.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,468 kB
  • sloc: python: 8,023; makefile: 18
file content (166 lines) | stat: -rw-r--r-- 5,384 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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.

.. code-block:: python
    :caption: python-jose

    from jose import jws

    signed = jws.sign({'a': 'b'}, 'your-secret-key', algorithm='HS256')
    jws.verify(signed, 'your-secret-key', algorithms='HS256')
    # the verify only returns the payload

.. code-block:: python
    :caption: joserfc

    import json
    from joserfc import jws
    from joserfc.jwk import OctKey

    key = OctKey.import_key("your-secret-key")
    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.

.. code-block:: python
    :caption: python-jose

    from jose import jwe

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

.. code-block:: python
    :caption: 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.

.. code-block:: python
    :caption: python-jose

    from jose import jwt

    encoded = jwt.encode({'a': 'b'}, 'your-secret-key', algorithm='HS256')
    jwt.decode(encoded, 'your-secret-key', algorithms='HS256')
    # => {'a': 'b'}

.. code-block:: python
    :caption: joserfc

    from joserfc import jwt
    from joserfc.jwk import OctKey

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

``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:

.. code-block:: python
    :caption: joserfc

    from typing import Any
    from joserfc import jws

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

``get_unverified_claims``
~~~~~~~~~~~~~~~~~~~~~~~~~

You can also use the ``jws.extract_compact`` method to extract the JWT's claims:

.. code-block:: python
    :caption: joserfc

    import json
    from typing import Any
    from joserfc import jws

    def get_unverified_claims(token: str) -> dict[str, Any]:
        obj = jws.extract_compact(token.encode())
        return json.loads(obj.payload)

JWK
---

In ``python-jose``, you can use ``jwk.construct`` to create a key instance
from a JWK-formatted dictionary. In contrast, ``joserfc`` provides the
``jwk.import_key`` method to achieve the same result.

.. code-block:: python
    :caption: joserfc

    from joserfc import jwk

    jwk.import_key({
        "kty": "oct",
        "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037",
        "use": "sig",
        "alg": "HS256",
        "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg"
    })