flask-principal icon indicating copy to clipboard operation
flask-principal copied to clipboard

Add documentation for using with flask-jwt

Open svenstaro opened this issue 10 years ago • 6 comments

Hi Matt,

since you are already the original author of flask-jwt and since flask-principal has the option to go without session, could you perhaps add a little example that goes beside the more classical flask-login example which shows how to properly use this with flask-jwt?

If you lack the time to do so properly, could you roughly describe me the process in this report for now?

svenstaro avatar Apr 17 '14 02:04 svenstaro

I'm also interested in this.

@mattupstate can you just provide a general overview how one would approach using flask-princpal with flask-jwt? Thanks!

iyn avatar Sep 14 '15 20:09 iyn

If this would still be valued, I'm going to tackle it over the next few weeks or so. I could write it up and do a PR if all goes well.

ghost avatar Dec 26 '15 19:12 ghost

Here is how I do it: JWT(app, authenticate, identity_loader)


def identity_loader(payload):
    user_id = payload['identity']

    try:
        current_user = User.query.filter_by(id=user_id).first()
        identity_changed.send(current_app._get_current_object(),
                              identity=Identity(user_id))
    except Exception as e:
        db_session.rollback()
        db_session.flush()
        raise e

    return current_user

orarbel avatar Apr 14 '16 16:04 orarbel

I'm using permissions and needs and adding the needs in the same place:

def identity_loader(payload):
    """Return user object referred to in payload."""
    username = payload["identity"]["username"] or None
    current_user = User(username=username)
    identity = Identity(username)
    if hasattr(current_user, "roles"):
        for role in current_user.roles:
             identity.provides.add(RoleNeed(role))
    identity_changed.send(current_app._get_current_object(),
                          identity=identity)
    return current_user


curator_permission = Permission(RoleNeed("Curator"))
curator_permission.description = "User must be a Curator"


@app.route("/projectEdit/<projectID>/<tableName>", methods=["POST"])
@jwt_required()
@curator_permission.require(http_exception=403)
def projectEdit(projectID, tableName):
    """ Update specified table for specified project."""

Just make sure that @jwt_required() comes ahead of the permission.

HarryPayne avatar Jun 03 '16 02:06 HarryPayne

Is there any documentation on how to do this now ? Wanted to do the same thing and was hoping to read up on it :)

AbdealiLoKo avatar May 02 '18 08:05 AbdealiLoKo

Would the following be a good identity loader as well?

@principal.identity_loader
def _identity_loader():
    if hasattr(current_user, 'id'):
        return Identity(current_user.id)

@user_loaded_from_request.connect_via(app)
def on_user_loaded_from_request(sender, user):
    identity_changed.send(
        flask.current_app._get_current_object(),
        identity=Identity(user.id)
    )

@identity_loaded.connect
def on_identity_loaded(sender, identity):

    # Set the identity user object
    identity.user = current_user

    if not hasattr(current_user, 'id'):
        return

    # Add the UserNeed to the identity
    identity.provides.add(UserNeed(current_user.id))

    for role in current_user.roles:
        identity.provides.add(RoleNeed(role.name))

Not quite sure why it's necessary to add an identity loader as Identity is already being instantiated in the user_loaded_from_request function when sending the identity_changed signal and I check for the presence of id in the identity_loaded function already but otherwise it doesn't work.

krisfris avatar Nov 13 '20 16:11 krisfris