Flask middleware on abort 401 causing a 500
--
Track title: CC F Haydns String Quartet No 53 in D
--
Chapters
00:00 Question
01:21 Accepted answer (Score 16)
02:50 Thank you
--
Full question
https://stackoverflow.com/questions/2926...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #flask #middleware #abort
#avk47
ACCEPTED ANSWER
Score 16
The middleware you've shown runs some other code and then calls the wrapped Flask application.  However, abort raises exceptions that Flask handles, but aren't handled by WSGI directly.  Since you're not in the Flask application yet, it can't handle the exception.
A much easier way would be to do this check inside the Flask app.  Create a before_request handler that does basically the same thing as the middleware, except you can use flask.request rather than needing to parse the path and headers yourself.
from flask import request, abort
@app.before_request
def check_auth_token():
    if request.path in ('/authenticate', '/token'):
        return
    token = request.headers.get('X-ACCESS-TOKEN')
    if not verify_token(token):
        abort(401)
    check_permissions(get_token_payload(token))
If you do want to use WSGI middleware for this, you need to create the response yourself. Conveniently, Werkzeug's exceptions behave like WSGI applications, so it's straightforward to use them.
from werkzeug.exceptions import Unauthorized
# in place of abort(401) in the middleware
return Unauthorized()(environ, start_response)
You can also use abort still by catching the exceptions it raises (which, again, are WSGI applications).
from werkzeug.exceptions import abort, HTTPException
# werkzeug.exceptions.abort is the same as flask.abort
try:
    abort(401)
except HTTPException as e:
    return e(environ, start_response)