vimalloc/flask-jwt-extended

Jwt_required and optional == True

hooverdirt opened this issue · 1 comments

This appears to be a bug unless I'm missing the requirement/intended functionality: If optional is True, I'm expecting jwt-extended not to raise any errors - however, I'm still getting a 401 - token missing error. I dug in a bit deeper in the code, and the issue seems to be that the verify_jwt_in_request method's error handler only catches NoAuthorizationError. However, _decode_jwt_from_config reraises ExpiredSignatureError....

stack:
jwt_required()
verify_jwt_in_request
_decode_jwt_from_request
decode_token
jwt_manager._decode_jwt_from_config <==

The only way to fix this is by adding the exception from the jwt manager to the verify_jwt_in_request method like so:

except (NoAuthorizationError, ExpiredSignatureError):       
        if not optional:
            raise
        g._jwt_extended_jwt = {}
        g._jwt_extended_jwt_header = {}
        g._jwt_extended_jwt_user = {"loaded_user": None}
        g._jwt_extended_jwt_location = None
        return None

Let me know if this makes sense

It is intentional this way. optional=True is designed to account for the case where no JWT is present in the request. If a JWT is present in the request, but it is invalid for any reason (expired, tampered with, whatever) then the normal error handlers will run for that.

I think this way is much safer, so you don't end up in a situation where you are acting as an anonymous user even though you are sending a JWT into the request, that feels off to me. But if you did need to support that for whatever reason, you could do so by writing a custom decorator and catching the resulting ExpiredSignatureError.