Changelogs » Flask-jwt-extended



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:

* added the `JWT_DECODE_AUDIENCE` configuration option, for using the `aud` claim in JWTs
* Change the `decode_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)`.
* If the `jti` claim doesn't exist in a token, it will now be set to `None` in the decoded dictionary instead of raising an error
* If the `type` claim doesn't exist in a token, it will be marked as an access token and `'type': 'access'` will be set in the decoded dictionary
* If the `fresh` 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 dictionary

Many thanks to acrossen for making this release possible!


* Include tests in (197)


* 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`. 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


* 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 (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 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.


* Allows passing JWTs in via the query string (117). Note that in most cases this is not a great idea, see the documentation as to why.
* Break out code to verify JWTs in a request into helper functions. This allows you to easily create your own decorators that utilize this extension (such as a `role_required` decorator), or hook up functionality to a flask before_request. (131)


* Allow option to unset access and refresh cookies independently of each other (148)


* Fixes JSON encoder added in 3.8.0 (140)


* Default to the Flask JSON encoder and allows for custom JSON encoders for encoding JWTs (139)


* Fixes a CSRF error when using jwts in cookies and the `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 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.

* Removed `PROPAGATE_EXCEPTIONS` setting from this extension
* Internal cleanup and refactoring


* `jwt_required` (et al) no longer require authorization to be present on an `OPTIONS` request (119)
* Add `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!


* Exports `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 until the timedelta is past (107). Thanks dunkmann00!


* Add ability to disable expires check for JWTs (105 and 106). Thanks beenje!


* Fix spelling, caused LICENSE file to not be properly included in pypi (88)


* 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 the version number once more. See the 3.3.2 release notes


* Add ability to change user claims name in token (92)
* Update unittest and convert test suite to pytest (77)
* Allow get_jwt_identity (et al) to work in `claims_verification_loader` (90)
* Dropped support for python 3.3 (89)
* Add LICENSE file to the pypi package (88)


* No longer returns the `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 (81)
* Register this extension with a flask app in a more proper way (043ba2390ee82920c6297e9334fee9113df8b8b5)


* Adds optional `jwt.claims_verification_loader` and `jwt.claims_verification_failed_loader` to do verification of the `user_claims` in an access token (refs 64 70)


* Fix some issues introduced in 3.1.0 when using a JWT_IDENTITY_CLAIM that is not 'identity' (67)


* Allows changing the identity claim name via JWT_IDENTITY_CLAIM options (65)


First off, sorry and advance, as this is a big breaking change for how blacklist and token revoking works. If you use these features, you will need to update your application accordingly to get everything working with the 3.x.x releases. If you are not using the token blacklisting/revoking features, you should be able to update to the 3.x.x releases without any issues.

Token revoking has always been the weakest part of this extension. It locked you in to a single (not overly efficient) way of doing things, and didn't provide any way to customize this feature to fit with your applications needs.This library always aimed to give you the tools needed so that you could do whatever it was you wanted to do with your application. Unfortunately, the original blacklist feature did not do this, and thus why I am making a large breaking change to introduce a new blacklisting system.

This new blacklisting system only requires that you give this extension a callback function that checks if a token has been revoked or not. It is now up to you to provide this function, as well as keeping track of the revoked tokens.

To upgrade to the 3.x.x branch, you will need to remove theapp.config['JWT_BLACKLIST_STORE'], and use your own code to store blacklisted tokens. You will also need to use the jwt.token_in_blacklist_loaderto provide a callback method which we use to check if a token is expired. Finally, if you are using app.config['JWT_BLACKLIST_STORE'] = 'all'', you will need to change it to app.config['JWT_BLACKLIST_STORE'] = ['access', 'refresh'].

Check out these links for examples that you can use with your application:


(I'm also generally available in IRC to help out if you have any questions. I am in `flask-jwt-extended` on `freenode`).

Final Note: I know breaking changes suck. I am very happy with where this extension is at now, and do not foresee any more breaking changes on the horizon. I will to do everything I can to prevent more breaking changes from here on out.

Change List
* JWT_BLACKLIST_STORE option has been removed.
* all simplekv code has been removed.
* JWT_BLACKLIST_TOKEN_CHECKS option now takes a string or a list of strings, and the valid strings are ['access', 'refresh'] instead of 'refresh' or  'all'.
* JWT_BLACKLIST_TOKEN_CHECKS option now defaults to ['access', 'refresh']. This is the equivalent  of the 'all' option in 2.x.x.
* Add jwt.token_in_blacklist_loader decorator. This is used to register a callback function for checking if a token has been blacklisted.
* Add decode_token(encoded_token) function, which lets you decode an encoded token.
* Users now needs to add tokens to the blacklist themselves, it is no longer automatically added in the create_access_token() and create_refresh_token() calls.


* Export get_jti(encoded_token) in (53)


* Adds user_loader feature (49 and 56): Documentation here: