Skip to content

Looking for recommended pattern to avoid "No matching state found in storage" #1587

@jgarplind

Description

@jgarplind

Issue

Our users face "No matching state found in storage" once in a while, in fact, often enough to be a concern.

Hopefully this is due to misconfiguration on our end, and if so this issue could be helpful for others too.

Context

We use v3.3.0 with oidc-client-ts v.3.2.0, in a Vite/React 18/React Router (declarative) app.

In the happy path, we have a route guard implementing a version of useAutoSignin (I also tried the library implementation, and it seems to have the same issues). Our implementation looks like this, based on an older version of the docs:

  // automatically sign-in
  useEffect(() => {
    if (
      !hasAuthParams() &&
      !isAuthenticated &&
      !activeNavigator &&
      !isLoading
    ) {
      signinRedirect({
        state: window.location.pathname,
      });
    }
  }, [isAuthenticated, activeNavigator, isLoading, signinRedirect]);

Following this flow, we're not sure if users ever face issues. At least we cannot reproduce them.

Reproduction

Instead, to reproduce the issue, I can go about it in 2 ways:

  1. Manually navigate to the post-redirect-destination URL, e.g. http://localhost:3000/login?code=1ABAC1819E0D7116424252F8F6F51983110FB73323C9912E57A34B51B467F4CA-1&scope=openid&state=16de9e797d504527804387146331b7d3&session_state=czrJc-zJU6oCpvt1oYawiSnLr7KqTAAZZ9oDPLatoew.B4AB755299D837CF49533F634CF83600&iss=https%3A%2F%2Fauth.example.com
  2. or navigate backwards in the browser history, leaving the client app and ending up on the issuer's login page again

What underlying issues are caused by the reproduction

Both flows bypass the part where signinRedirect sets state in local storage, thus the mechanisms in place to handle the login fail, and the user is faced with "No matching state found in storage".

Reproduction = real issue?

Again, I'm not sure if there are other ways our users are finding themselves in this place, but if these 2 cases can be mitigated, we would soon be informed if the issue still persists despite these reproductions no longer being possible.

Question

So, finally, concrete question: is there any reasonable way to guard against my 2 reproduciton paths?


Sidenotes

We do implement onSigninCallback in the recommended way.

Also, I did try to do a naive workaround like:

useEffect(() => {
  if (error?.message === "No matching state found in storage") {
    reLoginTried.current = true;
    signinRedirect();
  } else {
    reLoginTried.current = false;
  }
}, [error?.message, signinRedirect]);

it actually worked about 50% of the time, but the other 50% it would cause various Network/Operation aborted errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions