Storing Additional Data in JWTsΒΆ

You may want to store additional information in the access token which you could later access in the protected views. This can be done using the additional_claims argument with the create_access_token() or create_refresh_token() functions. The claims can be accessed in a protected route via the get_jwt() function.

It is important to remember that JWTs are not encrypted and the contents of a JWT can be trivially decoded by anyone who has access to it. As such, you should never put any sensitive information in a JWT.

from flask import Flask
from flask import jsonify
from flask import request

from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager

app = Flask(__name__)

app.config["JWT_SECRET_KEY"] = "super-secret"  # Change this!
jwt = JWTManager(app)


@app.route("/login", methods=["POST"])
def login():
    username = request.json.get("username", None)
    password = request.json.get("password", None)
    if username != "test" or password != "test":
        return jsonify({"msg": "Bad username or password"}), 401

    # You can use the additional_claims argument to either add
    # custom claims or override default claims in the JWT.
    additional_claims = {"aud": "some_audience", "foo": "bar"}
    access_token = create_access_token(username, additional_claims=additional_claims)
    return jsonify(access_token=access_token)


# In a protected view, get the claims you added to the jwt with the
# get_jwt() method
@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
    claims = get_jwt()
    return jsonify(foo=claims["foo"])


if __name__ == "__main__":
    app.run()

Alternately you can use the additional_claims_loader() decorator to register a callback function that will be called whenever a new JWT is created, and return a dictionary of claims to add to that token. In the case that both additional_claims_loader() and the additional_claims argument are used, both results are merged together, with ties going to the data supplied by the additional_claims argument.

# Using the additional_claims_loader, we can specify a method that will be
# called when creating JWTs. The decorated method must take the identity
# we are creating a token for and return a dictionary of additional
# claims to add to the JWT.
@jwt.additional_claims_loader
def add_claims_to_access_token(identity):
    return {
        "aud": "some_audience",
        "foo": "bar",
        "upcase_name": identity.upper(),
    }