Standard 401 response when using HTTP auth in flask
Custom error responses are really quite easy in Flask. Create a function whose only argument is the HTTP error status code, make it return a flask.Response instance, and decorate it with @app.errorhandler.
@app.errorhandler(401)
def custom_401(error):
return Response('<Why access is denied string goes here...>', 401, {'WWW-Authenticate':'Basic realm="Login Required"'})
You can then use abort(401)
to your heart's content.
Flask's abort
comes directly from Werkzeug. It is a callable object, that raises various predefined HTTP exceptions (subclasses of HTTPException
) on demand. Check out the code here for details.
The predefined Unauthorized
(which is mapped to 401) only defines the code and a message, but not the WWW-Authenticate
header, which as you know is required to trigger the login-popup with browsers. The headers an HTTPException
has are hardcoded as [('Content-Type', 'text/html')]
in HTTPException.get_headers
.
So to add the WWW-Authenticate
header, create your own Unauthorized
subclass, overwrite the get_headers
function and finally update the abort.mapping
dictionary with it.
from flask import abort
from werkzeug.exceptions import Unauthorized
class MyUnauthorized(Unauthorized):
description = '<Why access is denied string goes here...>'
def get_headers(self, environ):
"""Get a list of headers."""
return [
('Content-Type', 'text/html'),
('WWW-Authenticate', 'Basic realm="Login required"'),
]
abort.mapping.update({401: MyUnauthorized})
Now all abort(401)
calls will raise your custom exception.