flask-jwt-extended icon indicating copy to clipboard operation
flask-jwt-extended copied to clipboard

Having trouble with refresh tokens

Open rodericj opened this issue 11 months ago • 3 comments

I'm attempting to follow the instructions here: https://flask-jwt-extended.readthedocs.io/en/stable/refreshing_tokens.html for explicitly refreshing tokens.

I use:

 @app.before_request
    def beforeRequest():
         ...
         try
          ...
          except ExpiredSignatureError:
                abort(401, description="expired token") 

to capture expired tokens.

On the client side I am able to respond to this error and I call a refresh

@loginNamespace.route("/refresh", methods=["POST"])
class Refresh(Resource):

    # We are using the `refresh=True` options in jwt_required to only allow
    # refresh tokens to access this route.
    @jwt_required(refresh=True, locations= ["headers"])
    def post(self):
        identity = get_jwt_identity()
        access_token = create_access_token(identity=identity)
        return {"access_token": access_token}, 200

per the documentation.

I use this new access_token in my subsequent request to the protected resource and I get a 500 error indicating that the token that I am using is not the correct format:

binascii.Error: Invalid base64-encoded string: number of data characters (369) cannot be 1 more than a multiple of 4

It is unclear to me what I am supposed to be doing with the new access token that is created. I suppose it is possible that the refresh token itself is expired, but I would have exited the creation of the new access token to fail.

thanks in advance.

rodericj avatar Feb 25 '25 17:02 rodericj

Could you provide a full stack trace to help troubleshoot this?

vimalloc avatar Feb 28 '25 01:02 vimalloc


0"
INFO
Upon refresh, the identity is:  b6a9648a-42ba-42eb-a7f4-6dc436d8fbfc
INFO
10.214.65.67 - - [28/Feb/2025:05:12:28 +0000] "POST /auth/refresh HTTP/1.1" 200 393 "-" "SMSDelay/1 CFNetwork/1568.300.101 Darwin/24.2.0"
ERROR
[2025-02-28 05:12:28,759] ERROR in app: Exception on /messages/send [POST]
INFO
Traceback (most recent call last):
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask/app.py", line 917, in full_dispatch_request
INFO
    rv = self.dispatch_request()
INFO
         ^^^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask/app.py", line 902, in dispatch_request
INFO
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
INFO
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/api.py", line 402, in wrapper
INFO
    resp = resource(*args, **kwargs)
INFO
           ^^^^^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask/views.py", line 110, in view
INFO
    return current_app.ensure_sync(self.dispatch_request)(**kwargs)  # type: ignore[no-any-return]
INFO
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/resource.py", line 41, in dispatch_request
INFO
    resp = meth(*args, **kwargs)
INFO
           ^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_jwt_extended/view_decorators.py", line 170, in decorator
INFO
    return current_app.ensure_sync(fn)(*args, **kwargs)
INFO
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/marshalling.py", line 244, in wrapper
INFO
    resp = f(*args, **kwargs)
INFO
           ^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/marshalling.py", line 244, in wrapper
INFO
    resp = f(*args, **kwargs)
INFO
           ^^^^^^^^^^^^^^^^^^
INFO
  File "/opt/render/project/src/app/resources/messageResource.py", line 24, in post
INFO
    sendLater.delay(delay, messageText, current_user.phone_number)
INFO
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^
INFO
AttributeError: 'AnonymousUserMixin' object has no attribute 'phone_number'
INFO
Before request:  /messages/send
INFO
attempt to send later
INFO
10.214.65.67 - - [28/Feb/2025:05:12:28 +0000] "POST /messages/send HTTP/1.1" 500 37 "-" "SMSDelay/1 CFNetwork/1568.300.101 Darwin/24.2.0"

Doing this on mobile. Let me see if this looks reasonable here.

rodericj avatar Feb 28 '25 05:02 rodericj

That doesn't seem like it got the relevant error.


  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_jwt_extended/view_decorators.py", line 170, in decorator
    return current_app.ensure_sync(fn)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/marshalling.py", line 244, in wrapper
    resp = f(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_restx/marshalling.py", line 244, in wrapper
    resp = f(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/app/resources/messageResource.py", line 24, in post
    sendLater.delay(delay, messageText, current_user.phone_number)
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/werkzeug/local.py", line 318, in __get__
    obj = instance._get_current_object()
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/werkzeug/local.py", line 526, in _get_current_object
    return get_name(local())
                    ^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_login/utils.py", line 25, in <lambda>
    current_user = LocalProxy(lambda: _get_user())
                                      ^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_login/utils.py", line 370, in _get_user
    current_app.login_manager._load_user()
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_login/login_manager.py", line 378, in _load_user
    user = self._load_user_from_request(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_login/login_manager.py", line 441, in _load_user_from_request
    user = self._request_callback(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/app/__init__.py", line 74, in load_user_from_request
    api_key = base64.b64decode(api_key)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/python/Python-3.11.10/lib/python3.11/base64.py", line 88, in b64decode
    return binascii.a2b_base64(s, strict_mode=validate)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
binascii.Error: Incorrect padding
Before request:  /messages/send
attempt to send later
10.214.25.134 - - [28/Feb/2025:05:15:39 +0000] "POST /messages/send HTTP/1.1" 500 37 "-" "SMSDelay/1 CFNetwork/1568.300.101 Darwin/24.2.0

It's the incorrect padding that is what I was referring to. Seems like the refresh token is producing a new access token that is not in the correct format. I'm doing something wrong or I'm misunderstanding the API

rodericj avatar Feb 28 '25 05:02 rodericj