Reputation: 3059
I'm using Flask-HTTPAuth for authentication. I want to display different data from a view depending on if the request was authenticated or not. Decorating the view with auth.login_required
only shows it to authenticated users. How can I test if the request was authenticated with Flask-HTTPAuth?
auth = HTTPBasicAuth()
@app.route("/clothesInfo")
@auth.login_required
def show_info():
return jsonify(blah blah blah)
Upvotes: 4
Views: 1638
Reputation: 14674
Things are simpler since April 2020.
Flask-HTTPAuth 4.0.0 added optional
argument to login required
to do exactly this.
From the docs:
An optional optional argument can be set to True to allow the route to execute also when authentication is not included with the request, in which case auth.current_user() will be set to None. Example:
@app.route('/private') @auth.login_required(optional=True) def private_page(): user = auth.current_user() return "Hello {}!".format(user.name if user is not None else 'anonymous')
Upvotes: 1
Reputation: 127260
You can decorate a function that returns None
with login_required
. Calling it while not authenticated will return an error response, calling it while authenticated will return None
.
# a dummy callable to execute the login_required logic
login_required_dummy_view = auth.login_required(lambda: None)
def is_authenticated():
try:
# default implementation returns a string error
return login_required_dummy_view() is None
except HTTPException:
# in case auth_error_callback raises a real error
return False
@app.route('/info')
def info():
if is_authenticated():
# logged in view
else:
# basic view
See also Default login_required rather than adding decorator everywhere.
Upvotes: 3
Reputation: 67509
What you want is actually very easy to implement. In your verify_password
callback, you will get username and password set to ''
when the user does not provide credentials. You can still return True
from that function, and that will allow the anonymous user to access the endpoint.
The following example demonstrates this technique:
auth = HTTPBasicAuth()
@auth.verify_password
def verify_password(username, password):
if username == '' or password == '':
# anonymous user, we still let them in
g.current_user = None
return True
g.current_user = my_verify_function(username, password)
return g.current_user is not None
@app.route("/clothesInfo")
@auth.login_required
def show_info():
if g.current_user:
# prepare data for authenticated users here
pass
else:
# prepare data for anonymous users here
pass
return jsonify(data)
Upvotes: 6