pythonflaskwerkzeugflask-jwt-extended

Flask, flask-jwt-extended - trying to custom handle Unauthorized error


I am building a flask webapp and I am trying to return custom error message in case of 401 error which is raised when auth header is missing. For Authentication I use Flask-Jwt-Extended. I want to overwrite expired_token_loader(callback) to return 401 error and then catch it using @app.errohandler(401) and redirect to login.
So far I have done this:

@jwt.unauthorized_loader
def unauthorized_callback(callback):
    # Missing auth header
    # abort(401)
    return make_response("", 401)

@app.errorhandler(401)
def unauthorized(e):
    return "Custom 401 Error", 401

Found out in official Flask-JWT-Extended documentation that the function decorated with @jwt.unauthorized_loader must return a Flask Response.

So when I try to abort(401) as it is shown above and not return anything from unaturhorized_callback() it shows werkzeug.exceptions.Unauthorized: 401 Unauthorized: ...

And when I return make_response("", 401) it shows this, that means that the error handler did not handle the error:
enter image description here

EDIT: I am trying to redirect on trigger of the @jwt.unauthorized_loader so I wanted to throw an 401 error and then catch it with for example @app.errorhandler(401) and redirect.
I am doing this because I am also building a mobile app where I am catching 401 error and when I redirect inside the @jwt.unauthorized_loader it is always error 302, otherwise the redirect won't work. So I cannot do make_response(redirect("/login"), 401). So my goal is to throw 401 error and then handle it different ways in web app and mobile app. Thank you for help.


Solution

  • Not exactly what I wanted but in the end it did what I need. Insted of redirecting with custom http response code I did render_template with 401 code as shown below:

    @jwt.unauthorized_loader
    def unauthorized_callback(callback):
        # Missing auth header
        flash("Missing auth header please login")
        return make_response(render_template("login.html"), 401)