I'm using Flask Login and Principal for identity and role management. My needs are described straight out of the docs. My code is here:
@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
# Set the identity user object
identity.user = current_user
# Add the UserNeed to the identity
if hasattr(current_user, 'get_id'):
print 'current_user ' + str(current_user.get_id())
identity.provides.add(UserNeed(current_user.get_id))
# Assuming the User model has a list of roles, update the
# identity with the roles that the user provides
if hasattr(current_user, 'roles'):
if current_user.roles:
for role in current_user.roles:
identity.provides.add(RoleNeed(role.name))
In my login code I do this:
identity_changed.send(current_app._get_current_object(),
identity=Identity(user.user_id)
On login, the signal fires as expected. On each subsequent page load, the current_user is anonymous and doesn't have the user id yet all @login_required functions behave as if the user is logged in. Flask login knows that the user is logged in but for some reason the current_user is inconsistent.
Am I missing an essential point of configuration somewhere?
I encountered the same problem! The root cause is that both Flask-Login and Flask-Principal are invoked by Flask during the "preprocess" stage of the request in the order that they were registered with your Flask app. If you register Flask-Principal before you register Flask-Login, then @identity_loaded.connect_via(app)
will be called before @login_manager.user_loader
, and therefore current_user will return the anonymous user.
The Flask-Principal documentation example shows a code excerpt where Flask-Principal is registered before Flask-Login. Tsk tsk! Here's what I ended up doing in my bootstrap:
login_manager = LoginManager()
login_manager.init_app(app)
# ...
principals = Principal(app) # This must be initialized after login_manager.
Then in my users.py view file:
@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
""" This function is called by Flask-Principal after a user logs in. """
identity.user = current_user
if isinstance(current_user, User):
identity.provides.add(UserNeed(current_user.id))
for permission in user.permissions:
# Do permission-y stuff here.
This solved the problem for me.
Edit: I submitted a bug report to the project for the documentation.