NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1641 most downloaded on PyPI
Extended JWT integration with Flask
Last release 4 months ago
13 May 2026
Release timing varies
gaps range from 3 weeks to 1.5 years
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
92 releases · first in 2016
setup.py: bump PyJWT floor to >=2.11.0 to match the actual runtime requirement by @potiuk in #577
I'm skipping 4.7.2 because I forgot to bump the python version in code. This is the same as 4.7.2, with things setup correctly.
One column per quarter.
I'm skipping 4.7.2 because I forgot to bump the python version in code. This is the same as 4.7.2, with things setup correctly.
Oops
Add controls for verify_sub option in PyJWT by @jlucier in #562
Drop support for python 3.7 and 3.8, add 3.13 by @vimalloc in #559
Full Changelog: 4.6.0...4.7.0
Bump cryptography from 41.0.4 to 41.0.6 by @dependabot in #535
Full Changelog: 4.5.3...4.6.0
Replace "defining" with "define" by @lewisemm in #517
Full Changelog: 4.5.2...4.5.3
Fix documentation for stable build. No code changes were made in this release.
stable build. No code changes were made in this release.No changes from the 4.5.0 tag, I just forgot to update the __version__ which causes issues with publishing the release. This corrects that issue and b
No changes from the 4.5.0 tag, I just forgot to update the __version__ which causes issues with publishing the release. This corrects that issue and bumps the version to 4.5.1.
Fix compatibility with flask version 2.3 (#493). Huge shout out to @jrast for taking on the bulk of this work!
Full Changelog: https://github.com/vimalloc/flask-jwt-extended/compare/4.4.3...4.4.4
Documentation improvements ( #470). Thanks @Udit107710!
current_user in jinja templates by default (#478)current_user (#488)Full Changelog: https://github.com/vimalloc/flask-jwt-extended/compare/4.4.2...4.4.3
Fix mypy explicitly mark exported names #484 (thanks @KSmanis)
verify_type being set to False by default in verify_jwt_in_request() #483Full Changelog: https://github.com/vimalloc/flask-jwt-extended/compare/4.4.1...4.4.2
Documentation improvements (thanks @udoyen)
Full Changelog: https://github.com/vimalloc/flask-jwt-extended/compare/4.4.0...4.4.1
This decision comes because flask 1 is no longer being supported upstream and a recent dependency change they released made it difficult to continue t
verify_type argument to view decorators to allow accepting both refresh & access tokens #460 (thanks @tgross35)Allow Flask-JWT-Extended to work with new Cryptography versioning scheme
Allow overriding cookies domain at runtime (#446). Thanks @bejito!
Fix compatibility with Flask 1.x.x that was broke with the 4.2.2 release (see #437). Thanks @j178 for pointing this out!
Added async support to jwt_required view decorator (#436). Thanks @StefanVDWeide!
Update Flask-JWT-Extended to work with flask 2.x.x. (#427).
Add JWT_ENCODE_NBF configuration option to allow disabling the NBF claim during token creation. Thanks @magnunleno! #416
JWT_ENCODE_NBF configuration option to allow disabling the NBF claim during token creation. Thanks @magnunleno! #416get_jwt_request_location() function to determine where a token was parsed from in a request (useful for implicit token refresh with cookies). Thanks @sammck! #420@jwt_required(optional=True) was treating a request as if there was jwt present instead of handling the InvalidHeaderError. #421JWT_QUERY_STRING_VALUE_PREFIX configuration option. #421Allow JWT type to be things besides refresh or access (#401). Any type that is not refresh will be considered an access token. Thanks @sambonner for t
type to be things besides refresh or access (#401). Any type that is not refresh will be considered an access token. Thanks @sambonner for the PR!Properly include requirements.txt in the manifest.
requirements.txt in the manifest.This release contains many months of work and lots of breaking changes. For full details, please see: https://flask-jwt-extended.readthedocs.io/en/sta…
This release contains many months of work and lots of breaking changes. For full details, please see: https://flask-jwt-extended.readthedocs.io/en/stable/v4_upgrade_guide/
The only change it this release is that we are setting the metadata that marks this as the last release to support python versions earlier then 3.6 (i
Require PyJWT before version 2.0.0a to prevent breaking changes. (we will update to the 2.0.0 pyjwt release once it's out of the alpha/early release).
JWT_ENCODE_ISSUER optionFixes a bug where missing JWTs were not being handled gracefully, introduced in version 3.23.0
Adds the ability to add custom data to the JWT headers via the headers kwarg when making new tokens or via the jwt_manager.additional_headers_loader d
headers kwarg when making new tokens or via the jwt_manager.additional_headers_loader decorator. These headers can be accessed in your endpoints via the get_raw_jwt_header function. Thanks @iamajay for this feature! (#271)Make header reading compliant with RFC7230, section 3.2.2 (#270). Thanks @Croug!
Adds ability to check CSRF double submit token from form data instead of headers (#269). Thanks @colevscode!
Move docs to pallets-sphinx-themes
JWT_DECODE_ISSUER option for use with other JWT providers (#259)Look for JWTs in the same order that they are defined in JWT_TOKEN_LOCATION. Thanks @stephendwolff!
JWT_TOKEN_LOCATION. Thanks @stephendwolff!(#256)Adds support for using multiple algorithms for decoding JWTs. Thanks @Darkheir!
Fix JWT_SESSION_COOKIE = False creating a cookie that was too long in the future for some browsers (#243). Thanks @allen-cook!
JWT_SESSION_COOKIE = False creating a cookie that was too long in the future for some browsers (#243). Thanks @allen-cook!Fixes an issue when using decode_token on an expired token. This issue was introduced in 3.16.0.
decode_token on an expired token. This issue was introduced in 3.16.0. (#234)1.6.4 or newer (#238)Add the ability to dynamically set user claims via the new user_claims argument to create_access_token and create_refresh_token functions (#229). Than
user_claims argument to create_access_token and create_refresh_token functions (#229). Thanks @jeanphixdatetime.datetime (such as dateutil) will now work with extension (#233). Thanks @abathurAdd the ability to use an integer (seconds) for the JWT_ACCESS_TOKEN_EXPIRES and JWT_REFRESH_TOKEN_EXPIRES settings. (#226) Thanks @evangilo!
JWT_ACCESS_TOKEN_EXPIRES and JWT_REFRESH_TOKEN_EXPIRES settings. (#226) Thanks @evangilo!…out from under you. You will however receive a deprecation warning when using that way. To fix this, simply add an addition argument to your callback…
This release changes how the @jwt.expired_token_loader callback function works. Before this release the callback function took no arguments. Now it will take one argument which is the decoded contents of the expired token. This lets you customize the expired token callback based on the token that was received. For example:
# Old way
@jwt.expired_token_loader
def old_expired_callback():
return jsonify(foo='bar'), 401
# New way
@jwt.expired_token_loader
def new_expired_callback(expired_token):
if expired_token['type'] == 'access':
return jsonify(foo='bar'), 401
else:
return jsonify(foo='baz'), 401
The old way will still work, updating to this version will not break your software out from under you. You will however receive a deprecation warning when using that way. To fix this, simply add an addition argument to your callback function for the expired token.
Adds the JWT_DECODE_LEEWAY option (#218). Thanks @otetard!
JWT_DECODE_LEEWAY option (#218). Thanks @otetard!In this release we are modifying how decoded tokens work, so that this extension can be more easily used by other JWT providers (#212). The important
In this release we are modifying how decoded tokens work, so that this extension can be more easily used by other JWT providers (#212). The important changes in this release are:
JWT_DECODE_AUDIENCE configuration option, for using the aud claim in JWTsdecode_key_callback() function to now take the unverified headers as well as the unverified claims as arguments. If you have existing code that only takes one argument, it will still work, but you will see a depreciation warning when it is called. You should update your callback to take a second parameter to fix that. As an example decode_key(claims) would become decode_key(claims, headers).jti claim doesn't exist in a token, it will now be set to None in the decoded dictionary instead of raising an errortype claim doesn't exist in a token, it will be marked as an access token and 'type': 'access' will be set in the decoded dictionaryfresh claim doesn't exist in a token, it will be marked as a non-fresh token and 'fresh': False will be set in the decoded dictionaryMany thanks to @acrossen for making this release possible!
* Include tests in MANIFEST.in
Add support for custom encode and decode keys (#91). There are now two new callbacks that can be registered: decode_key_loader and encode_key_loader.
decode_key_loader and encode_key_loader. The decode callback is passed in the unverified JWT claims, and must return a string that will be used to decode and verify the JWT. The encode callback is passed in the identity (as passed in to the create_access_token or create_refresh_token functions) and must return a string that will be used to encode a JWT. If unset, the JWT_SECRET_KEY, JWT_PUBLIC_KEY, or JWT_PRIVATE_KEY will still be used as appropriate.Requires cryptography >= 2.3 in response to https://nvd.nist.gov/vuln/detail/CVE-2018-10903
Add ability to get the JWT from the JSON body of the request (#173). Thanks @luord!!
Adds new JWT_ERROR_MESSAGE_KEY option to change the JSON key on the default error messages
JWT_ERROR_MESSAGE_KEY option to change the JSON key on the default error messages (#160)Adds new JWT_CLAIMS_IN_REFRESH_TOKEN configuration option, which if set to true will cause the user claims to be loaded into refresh tokens as well as
JWT_CLAIMS_IN_REFRESH_TOKEN configuration option, which if set to true will cause the user claims to be loaded into refresh tokens as well as access tokens (#100).I forgot to actually increase the version number on the 3.9.0 release. Whoops. Nothing new from 3.9.0 minus a the version number fix.
I forgot to actually increase the version number on the 3.9.0 release. Whoops. Nothing new from 3.9.0 minus a the version number fix.
Allow option to unset access and refresh cookies independently of each other
Fixes JSON encoder added in 3.8.0
Default to the Flask JSON encoder and allows for custom JSON encoders for encoding JWTs
Fixes a CSRF error when using jwts in cookies and the @jwt_optional decorator
@jwt_optional decorator (#129)In this release, we are no longer toggling the flask PROPAGATE_EXCEPTIONS = True setting in this extension. It was set in here initially to get things
In this release, we are no longer toggling the flask PROPAGATE_EXCEPTIONS = True setting in this extension. It was set in here initially to get things working with flask-restful, but setting a global flask option in here just so that it would work with another flask extension was a poor design choice.
Note that if you are using flask-restful (or possibly other extensions) and the error handlers stop working after this update, you will need to manually set the PROPAGATE_EXCEPTIONS setting in your configuration to keep everything working. Sorry all the inconvenience.
PROPAGATE_EXCEPTIONS setting from this extension@jwt_required (et al) no longer require authorization to be present on an OPTIONS request
@jwt_required (et al) no longer require authorization to be present on an OPTIONS request (#119)Add Werkzeug>=0.14 to install requirements (#115)Adds ability to use the samesite cookie attribute (#34, #113, #115). Requires Werkzeug >= 0.14. Thanks @farshiana!
samesite cookie attribute (#34, #113, #115). Requires Werkzeug >= 0.14. Thanks @farshiana!Exports get_csrf_token to the api
get_csrf_token to the api (#112)Add ability to set the fresh argument when creating access tokens to a datetime.timedelta, which will cause the token to be marked as fresh from now u
fresh argument when creating access tokens to a datetime.timedelta, which will cause the token to be marked as fresh from now until the timedelta is past (#107). Thanks @dunkmann00!Add ability to disable expires check for JWTs (#105 and #106). Thanks @beenje!
Fix MANIFEST.in spelling, caused LICENSE file to not be properly included in pypi
Previous test of 3.3.2 (for adding license file) caused pypi to not allow 3.3.2 to be reused, even though that release was nuked. Just incrementing th
No longer returns the InvalidHeaderError handler if an authorization header appears in a different format then we expect in the @jwt_optional endpoint
InvalidHeaderError handler if an authorization header appears in a different format then we expect in the @jwt_optional endpoint. (refs #82)Add possibility to set up cookies max-age during runtime
Adds optional @jwt.claims_verification_loader and @jwt.claims_verification_failed_loader to do verification of the user_claims in an access token (ref
@jwt.claims_verification_loader and @jwt.claims_verification_failed_loader to do verification of the user_claims in an access token (refs #64 #70)Your coding agent can read these notes before it upgrades. Set up the MCP server →