Error after Keycloak login "No matching state found in storage"
I try to use react-oidc-context in a small example project. Most of it based on the code of this README.md. It seems like the onSigninCallback is not working properly and I need a second login to get the correct state, token and user info.
This is the behavior
- click login button (call signinRedirect() )
- redirected to Keycloak
- login with my username/password
- redirected back to my app and path /oauth2/callback + parameters in URL
- ERROR: "No matching state found in storage"
- (at this time, the onSignInCallback was not triggered!)
- click on the login button again (call signinRedirect(), exactly like the first time)
- without getting redirected a second time to Keycloak, onSigninCallback is triggered and I am logged in!
keycloakConfig.tsx
export const signinCallback = (_user: User | void): void => {
console.log("onSigninCallback");
console.log(_user);
window.history.replaceState(
{},
document.title,
window.location.pathname
)
}
export const oidcConfig:AuthProviderProps = {
authority: "http://127.0.0.1:7080/realms/test",
client_id: "frontend",
// This redirect URI needs to match exactly your configuration in Keycloak!
//redirect_uri: "http://127.0.0.1:5173",
redirect_uri: "http://127.0.0.1:5173/oauth2/callback",
onSigninCallback: signinCallback
};
main.tsx
import { AuthProvider } from 'react-oidc-context';
import { oidcConfig } from './keycloakConfig.tsx';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<AuthProvider {...oidcConfig}>
<App />
</AuthProvider>
</StrictMode>,
)
App.tsx
import { useAuth } from 'react-oidc-context';
function App() {
const {isAuthenticated, isLoading, error, user, settings, activeNavigator, removeUser, signinRedirect} = useAuth();
console.log(settings);
switch (activeNavigator) {
case "signinSilent":
return <div>Signing you in...</div>;
case "signoutRedirect":
return <div>Signing you out...</div>;
}
if (isLoading) {
return <div>Loading...</div>;
}
if (isAuthenticated) {
return (
<div>
Hello {user?.profile.sub}{" "}
<p>{JSON.stringify(user)}</p>
<button onClick={() => void removeUser()}>Log out</button>
</div>
);
}
return (
<div>
{(error ? <div>Oops... {error.message}</div> : <></>)}
<button onClick={() => void signinRedirect()}>Log in</button>
</div>
);
}
@debegr92 - We're seeing the same thing with our project, however it works on a local development machine - but not when we deploy to a test server.
Did you have any luck finding a solution?
Hi @debegr92 and @gidich - are either of you able to reproduce this error in the keycloak sample repo?
Okay, here is what I did @zach-betz-hln
- Clone the repository https://github.com/authts/sample-keycloak-react-oidc-context
- cd inside react
- Add .env with VITE_AUTHORITY and VITE_CLIENT_ID
- change src/config.ts to use my redirect_uri http://127.0.0.1:5173/oauth2/callback
- npm install
- npm run dev
Same result. First login shows "no matching state".
Logout and login again then works (the default router shows nothing for my callback route, but I can see the home button and my token).
I am using a working Keycloak cloud instance and try to implement the user login on my local machine. So therefore I added the 127.0.0.1 as valid redirect URL in Keycloak.
@debegr92 - Interesting. Now I am wondering about the config of your Keycloak cloud instance.
One thing you could try with the sample repo is running it once with default config, then again pointed to your Keycloak cloud instance, and compare the responses in the DevTools Network tab.
Do your usual login/logout flow then compare the responses in each run for relevant differences.