Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question/need help: how to handle "LogtoException: Invalid state in the callback URI" #33

Open
1 of 4 tasks
humpydonkey opened this issue Jan 16, 2025 · 1 comment
Open
1 of 4 tasks
Assignees
Labels
bug Something isn't working

Comments

@humpydonkey
Copy link

Describe the bug

I'm integrating logto cloud into my fastapi service with testing/development tenant.
I have seen this exception a few times while i was testing logto sign in flow:

logto.LogtoException.LogtoException: Invalid state in the callback URI

It doesn't happen consistently. I suspect it's due to multiple concurrent calls like below occurred causing it, but i'm not sure. I saw two calls like below.

https://auth.vid-craft.com/oidc/auth?client_id=87t2l9siglorrxfcslsgl&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fapi%2Fv1%2Fauth%2Fcallback&response_type=code&scope=openid+profile+email+phone+openid+offline_access+profile&prompt=consent&code_challenge=5QI8ErAmmqx0nBuEoMD318aZbjOsJJvB-TF7hpsD5VM&code_challenge_method=S256&state=LSoyZ3SvYQJfPe2vxGrMp9OnfBvJMVG0aCNk-sK5BlY&interaction_mode=signUp

Expected behavior

This may not be a bug, it's more of a question/asking for help.
My questions are:

  1. why does it happen? what's the root cause?
  2. how to handle this kind of exception in the server side?

How to reproduce?

The call that failed looks like below from my Chrome developer tool:

http://localhost:8000/api/v1/auth/callback?code=KdfejSLR7se2JBZeRgRutT8fp5BpFe38WITmx1AwJQM&state=5Aq2ukAcE-4m94UNT-XSeKvYYyjX5GzV1kAszXE0ylM&iss=https%3A%2F%2Fauth.vid-craft.com%2Foidc

Context

INFO:     127.0.0.1:53296 - "GET /api/v1/auth/callback?code=KdfejSLR7se2JBZeRgRutT8fp5BpFe38WITmx1AwJQM&state=5Aq2ukAcE-4m94UNT-XSeKvYYyjX5GzV1kAszXE0ylM&iss=https%3A%2F%2Fauth.vid-craft.com%2Foidc HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
  + Exception Group Traceback (most recent call last):
  |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 77, in collapse_excgroups
  |     yield
  |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 186, in __call__
  |     async with anyio.create_task_group() as task_group:
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 736, in __aexit__
  |     raise BaseExceptionGroup(
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
    |     result = await app(  # type: ignore[func-returns-value]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    |     return await self.app(scope, receive, send)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    |     await super().__call__(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    |     await self.middleware_stack(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __call__
    |     raise exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __call__
    |     await self.app(scope, receive, _send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 185, in __call__
    |     with collapse_excgroups():
    |          ^^^^^^^^^^^^^^^^^^^^
    |   File "/opt/homebrew/Cellar/[email protected]/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py", line 158, in __exit__
    |     self.gen.throw(value)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 83, in collapse_excgroups
    |     raise exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 187, in __call__
    |     response = await self.dispatch_func(request, call_next)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/app/main.py", line 102, in monitor_worker_health
    |     response = await call_next(request)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 163, in call_next
    |     raise app_exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 149, in coro
    |     await self.app(scope, receive_or_disconnect, send_no_error)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 185, in __call__
    |     with collapse_excgroups():
    |          ^^^^^^^^^^^^^^^^^^^^
    |   File "/opt/homebrew/Cellar/[email protected]/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py", line 158, in __exit__
    |     self.gen.throw(value)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 83, in collapse_excgroups
    |     raise exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 187, in __call__
    |     response = await self.dispatch_func(request, call_next)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/app/main.py", line 86, in dispatch
    |     response = await call_next(request)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 163, in call_next
    |     raise app_exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 149, in coro
    |     await self.app(scope, receive_or_disconnect, send_no_error)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/cors.py", line 85, in __call__
    |     await self.app(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    |     raise exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    |     await app(scope, receive, sender)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
    |     await self.middleware_stack(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
    |     await route.handle(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
    |     await self.app(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
    |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    |     raise exc
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    |     await app(scope, receive, sender)
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
    |     response = await f(request)
    |                ^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
    |     raw_response = await run_endpoint_function(
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
    |     return await dependant.call(**values)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/Users/asia/work/vid_craft/backend/app/api/routes/auth.py", line 23, in callback
    |     await LOGTO_CLIENT.handleSignInCallback(str(request.url))
    |   File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/logto/LogtoClient.py", line 377, in handleSignInCallback
    |     raise LogtoException("Invalid state in the callback URI")
    | logto.LogtoException.LogtoException: Invalid state in the callback URI
    +------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __call__
    raise exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 185, in __call__
    with collapse_excgroups():
         ^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py", line 158, in __exit__
    self.gen.throw(value)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 83, in collapse_excgroups
    raise exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 187, in __call__
    response = await self.dispatch_func(request, call_next)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/app/main.py", line 102, in monitor_worker_health
    response = await call_next(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 163, in call_next
    raise app_exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 149, in coro
    await self.app(scope, receive_or_disconnect, send_no_error)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 185, in __call__
    with collapse_excgroups():
         ^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py", line 158, in __exit__
    self.gen.throw(value)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_utils.py", line 83, in collapse_excgroups
    raise exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 187, in __call__
    response = await self.dispatch_func(request, call_next)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/app/main.py", line 86, in dispatch
    response = await call_next(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 163, in call_next
    raise app_exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/base.py", line 149, in coro
    await self.app(scope, receive_or_disconnect, send_no_error)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/cors.py", line 85, in __call__
    await self.app(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 62, in wrapped_app
    raise exc
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 51, in wrapped_app
    await app(scope, receive, sender)
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/asia/work/vid_craft/backend/app/api/routes/auth.py", line 23, in callback
    await LOGTO_CLIENT.handleSignInCallback(str(request.url))
  File "/Users/asia/work/vid_craft/backend/.venv/lib/python3.12/site-packages/logto/LogtoClient.py", line 377, in handleSignInCallback
    raise LogtoException("Invalid state in the callback URI")
logto.LogtoException.LogtoException: Invalid state in the callback URI
  • Logto Cloud
  • Self-hosted, Logto version =
    • Container (Docker image)
    • Raw Node.js

Screenshots

@humpydonkey humpydonkey added the bug Something isn't working label Jan 16, 2025
@darcyYe
Copy link
Contributor

darcyYe commented Jan 17, 2025

If you are receiving multiple /callback requests on the front end, there must be an issue with the code implementation.

In the /callback process, we validate the state stored in sessionStorage. Upon successful validation, we retrieve the access token and clear the sessionStorage. This results in subsequent /callback requests inevitably failing, as the state cannot be retrieved from sessionStorage for comparison. Please refer to the authorization code flow for a deeper understanding of the process.

If you can provide a code repo with your implementation that result in this error message, that can help us locate the issue.

@darcyYe darcyYe self-assigned this Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

2 participants