Skip to content

Commit 142f39f

Browse files
author
Landon Gilbert-Bland
committed
Finish 4.0.0 breaking changes documentation
1 parent 79f69ce commit 142f39f

File tree

3 files changed

+128
-198
lines changed

3 files changed

+128
-198
lines changed

4.0.0_changelog.md

Lines changed: 0 additions & 198 deletions
This file was deleted.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ Flask-JWT-Extended's Documentation
2121
changing_default_behavior
2222
custom_decorators
2323
api
24+
v4_upgrade_guide

docs/v4_upgrade_guide.rst

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
4.0.0 Breaking Changes and Upgrade Guide
2+
========================================
3+
This release includes a lot of breaking changes that have been a long time coming,
4+
and will require some manual intervention to upgrade your application. Breaking
5+
changes are never fun, but I really believe they are for the best. As a result
6+
of all these breaking changes, this extension should be simpiler to use,
7+
provide more flexibility, and allow for easier additions to the API without
8+
introducing further breaking changes in the future. Here are all the breaking
9+
changes that might affect your flask application when upgrading to 4.0.0.
10+
11+
12+
Encoded JWT Changes (IMPORTANT)
13+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14+
- The ``JWT_USER_CLAIMS`` configuration option has been removed. Now when creating
15+
JWTs with additional claims, those claims areput on the top level of the token,
16+
insetad of inside the the nested ``user_claims`` dictionary. This has the very
17+
important benefit of allowing you to override reserved claims (such as ``nbf``)
18+
which was not previously possible in this extension.
19+
20+
**IMPORTANT NOTE**:
21+
22+
This has the unfortunate side effect that any existing JWTs your application is
23+
using will not work correctly if they utilize additional claims. We **strongly**
24+
suggest changing your secret key to force all users to get the new format of
25+
JWTs. If that is not feasible for your appilication you could build a shim to
26+
handle both the old JWTs which store additional claims in the ``user_claims``
27+
key, and the new format where additional claims are now stored at the top
28+
level, until all the JWTs have had a chance to cycle to the new format.
29+
- The default ``JWT_IDENTITY_CLAIM`` option is now ``sub`` instead of ``identity``.
30+
31+
General Changes
32+
~~~~~~~~~~~~~~~
33+
- Dropped support for everything before Python 3.6 (including Python 2).
34+
- Requires PyJWT >= 2.0.0.
35+
- Depreciation warnings in ``3.25.2`` have been removed and are now errors:
36+
37+
- The ``JWT_CSRF_HEADER_NAME`` option has removed.
38+
- The ``jwt.expired_token_loader`` will error if the callback does not take
39+
an argument for the expired token header and expired token payload.
40+
- The ``jwt.decode_key_loader`` will error if the callback does not take an argument
41+
for the unverified_headers and the unverified_payload.
42+
43+
- Calling ``get_jwt()``, ``get_jwt_header()``, or ``get_jwt_identity()`` will raise
44+
a ``RuntimeError`` when called outside of a protected context (ie if you forgot
45+
``@jwt.required()`` or ``verify_jwt_in_request()``). Previously these calls
46+
would return ``None``.
47+
- Calling ``get_jwt()`` or ``get_jwt_header()`` will return an emptry dictionary
48+
if called from an optionally protected endpoint. Previously this would return ``None``.
49+
- Calling ``get_current_user()`` or ``current_user`` will raise a ``RuntimeError``
50+
if no ``@jwt.user_lookup_loader`` callback is defined.
51+
52+
Blacklist Changes
53+
~~~~~~~~~~~~~~~~~
54+
- All occurrences of ``blacklist`` have been renamed to ``blocklist``
55+
- The ``JWT_BLACKLIST_ENABLED`` option has been removed. If you do not want to
56+
check a JWT against your blocklist, do not register a callback function with
57+
``@jwt.token_in_blocklist_loader``.
58+
- The ``JWT_BLACKLIST_TOKEN_CHECKS`` option has been removed. If you don't want
59+
to check a given token type against the blocklist, specifically ignore it in
60+
your callback function by checking the ``jwt_payload["type"]`` and short
61+
circuiting accordingly. ``jwt_payload["type"]`` will be either ``"access"`` or ``"refresh"``.
62+
63+
Callback Function Changes
64+
~~~~~~~~~~~~~~~~~~~~~~~~~
65+
- Renamed ``@jwt.claims_verification_loader`` to ``@jwt.token_verification_loader``
66+
- Renamed ``@jwt.claims_verification_failed_loader`` to ``@jwt.token_verification_failed_loader``
67+
- Renamed ``@jwt.user_claims_loader`` to ``@jwt.additional_claims_loader``
68+
- Renamed ``@jwt.user_in_blacklist_loader`` to ``@jwt.user_in_blocklist_loader``
69+
- Renamed ``@jwt.user_loader_callback_loader`` to ``@jwt.user_lookup_loader``
70+
- Renamed ``@jwt.user_loader_error_loader`` to ``@jwt.user_lookup_error_loader``
71+
- The following callback functions have all been changed to take two arguments.
72+
Those arguments are the ``jwt_headers`` and ``jwt_payload``.
73+
74+
- ``@jwt.needs_fresh_token_loader``
75+
- ``@jwt.revoked_token_loader``
76+
- ``@jwt.user_lookup_loader``
77+
- ``@jwt.user_lookup_error_loader``
78+
- ``@jwt.expired_token_loader``
79+
- ``@jwt.token_in_blocklist_loader``
80+
- ``@jwt.token_verification_loader``
81+
- ``@jwt.token_verification_failed_loader``
82+
83+
.. code-block :: python
84+
85+
@jwt.revoked_token_loader
86+
def revoked_token_response(jwt_header, jwt_payload):
87+
return jsonify(msg=f"I'm sorry {jwt_payload['sub']} I can't let you do that")
88+
89+
- The arguments for ``@jwt.decode_key_loader`` have been reversed to be consistent
90+
with the rest of the application. Previously the arguments were ``(jwt_payload, jwt_headers)``.
91+
Now they are ``(jwt_headers, jwt_payload)``.
92+
93+
API Changes
94+
~~~~~~~~~~~
95+
- All view decorators have been moved to a single decorator:
96+
- ``@jwt_required`` is now ``@jwt_required()``
97+
- ``@jwt_optional`` is now ``@jwt_required(optional=True)``
98+
- ``@fresh_jwt_required`` is now ``@jwt_required(fresh=True)``
99+
- ``@jwt_refresh_token_required`` is now ``@jwt_required(refresh=True)``
100+
- All additional ``verify_jwt_in_request`` functions have been moved to a single method:
101+
- ``verify_jwt_in_request_optional()`` is now ``verify_jwt_in_request(optional=True)``
102+
- ``verify_jwt_refresh_token_in_request()`` is now ``verify_jwt_in_request(refresh=True)``
103+
- ``verify_fresh_jwt_in_request()`` is now ``verify_jwt_in_request(fresh=True)``
104+
- Renamed ``get_raw_jwt()`` to ``get_jwt()``
105+
- Renamed ``get_raw_jwt_headers()`` to ``get_jwt_headers()``
106+
- Removed ``get_jwt_claims()``. Use ``get_jwt()`` instead.
107+
- The ``headers`` argument in ``create_access_token()`` and ``create_refresh_token()``
108+
has been renamed to ``additional_headers``.
109+
110+
- If you pass in the ``additional_headers``, it will now be merged with the
111+
headers returned by the ``@jwt.additional_headers_loader`` callback, with
112+
ties going to the ``additional_headers`` argument.
113+
114+
- The ``user_claims`` argument in ``create_access_token()`` and ``create_refresh_token()``
115+
has been renamed to ``additional_claims``.
116+
117+
- If you pass in the ``additional_claims`` option, it will now be merged with
118+
the claims returned by the ``@jwt.additional_claims_loader`` callback, with
119+
ties going to the ``additional_claims`` argument.
120+
121+
- The ``JWT_VERIFY_AUDIENCE`` option has been removed. If you do not want to verify
122+
the JWT audience (``aud``) claim, simply do not set the ``JWT_DECODE_AUDIENCE``
123+
option.
124+
- The ``JWT_CLAIMS_IN_REFRESH_TOKEN`` option has been removed. Additional claims
125+
will now always be put in the JWT regardless of if it is an access or refresh
126+
tokens. If you don't want additional claims in your refresh tokens, do not
127+
include any additional claims when creating the refresh token.

0 commit comments

Comments
 (0)