Skip to content

Refresh token with complex object  #100

@kush99993s

Description

@kush99993s

Hello everyone,

I am trying to do is refresh token with complex object. My code is as follows:

from flask import Blueprint, jsonify, request
from flask_jwt_extended import jwt_required, create_access_token, \
    jwt_refresh_token_required, create_refresh_token,\
    get_jwt_identity, get_jwt_claims
from utility import to_dict
from my_app.auth.models import User
from my_app import app
from flask_jwt_extended import JWTManager


auth = Blueprint("auth", __name__)
jwt = JWTManager(app)


# This is an example of a complex object that we could build
# a JWT from. In practice, this will likely be something
# like a SQLAlchemy instance.
class UserObject:
    def __init__(self, username, roles):
        self.username = username
        self.roles = roles


# Create a function that will be called whenever create_access_token
# is used. It will take whatever object is passed into the
# create_access_token method, and lets us define what custom claims
# should be added to the access token.
@jwt.user_claims_loader
def add_claims_to_access_token(user):
    return {'roles': user.roles}


# Create a function that will be called whenever create_access_token
# is used. It will take whatever object is passed into the
# create_access_token method, and lets us define what the identity
# of the access token should be.
@jwt.user_identity_loader
def user_identity_lookup(user):
    return user.username


@auth.route('/login', methods=['POST'])
def login():
    data = to_dict(request.form, request.args, request.get_json())
    username = data['username']
    password = data['password']

    if (username is None) or (password is None):
        return jsonify({"msg": "Bad username or password"}), 401

    log_user = User(username, password)

    if not log_user.IsUser:
        return jsonify({"msg": "Bad username or password"}), 401

    if len(log_user.dashboard_groups) == 0:
        return jsonify({"msg": "Forbidden"}), 403

    user = UserObject(log_user.username, log_user.roles)

    ret = {
        'access_token': create_access_token(identity=user),
        'refresh_token': create_refresh_token(identity=user)
    }
    return jsonify(ret), 200


# The jwt_refresh_token_required decorator insures a valid refresh
# token is present in the request before calling this endpoint. We
# can use the get_jwt_identity() function to get the identity of
# the refresh token, and use the create_access_token() function again
# to make a new access token for this identity.
@auth.route('/refresh', methods=['POST'])
@jwt_refresh_token_required
def refresh():
    user = UserObject(get_jwt_identity(), get_jwt_claims())
    ret = {
        'access_token': create_access_token(identity=user),
        'refresh_token': create_refresh_token(identity=user)
    }
    return jsonify(ret), 200


@auth.route('/protected', methods=['GET'])
@jwt_required
def protected():
    username = get_jwt_identity()
    roles = get_jwt_claims()
    print(roles)
    return jsonify(logged_in_as=username), 200

If I log in using my username and password, login function works just fine, I get my refresh token and access token. then If I hit protected endpoint, it works fine, it prints me all roles that I have store.

However, if I hit refresh endpoint, then hit protected endpoint, I don't see any roles printed. I believe when I try to connect to refresh endpoint. I loose all role related data. when I print(get_jwt_claims()), it doesn't print anything in refresh end point.

If I am not wrong, when I hist refresh endpoint then it is looking for roles base upon refresh token. which is null and that is creating issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions