-
Notifications
You must be signed in to change notification settings - Fork 89
Description
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:
- 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
- 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.