I would like to have the following authentication scheme
However, I don't fully understand the inner working of flask-login. My preliminary understanding is that
login_user and flask-login creates a session to store user information (maybe user_id?)login_required decorator is usedI thought only request_loader would be needed if JWT authentication is used because all we need to do is check every request header. But if only the request_loader function is provided (see code below), exception is thrown.
Exception: No user_loader has been installed for this LoginManager. Add one with the 'LoginManager.user_loader' decorator.
More specifically, my questions are
user_loader and request_loader if we are to use JWT authentication?user_loader and request_loader being called, if both of them are provided? user_loader if request_loader is provided?Here are my implementation of these two loaders
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@login_manager.request_loader
def load_user_from_request(request):
auth_str = request.headers.get('Authorization')
token = auth_str.split(' ')[1] if auth_str else ''
if token:
user_id = User.decode_token(token)
user = User.query.get(int(user_id))
if user:
return user
return None
I notice the exception of
Exception: No user_loader has been installed for this LoginManager. Add one with the 'LoginManager.user_loader' decorator.
is caused by the the logout handler given as follows
@auth.route('/logout')
@login_required
def logout():
logout_user()
flash('You have logged out.')
return redirect(url_for('home.index'))
The reason is that flask-login needs to figure out which user to log out, which is done by calling a utils._get_user() function, which calls login_manager._load_user(), which further calls login_manager.reload_user(), and reload_user() will try to call the function login_manager.user_loader decorates which converts the user_id stored in the session to a user instance.
Thus as a workaround, one can define this function login_manager.user_loader decorates. I still think it's kind of a bug because the request alone is able to determine the user instance already, isn't that the purpose of request_loader?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With