Oidc-client-js: Navigate back to login (browser back button) and then login => No matching state found in storage

Created on 4 Sep 2019  路  4Comments  路  Source: IdentityModel/oidc-client-js

If you navigate to id server login page by press back button and clicks on login again, we get the error No matching state found in storage. This error is reproducible in the samples as well.
The apparent reason is: before sending the redirect call state is set in the storage and once the sign in is complete state is removed from storage. Now if user clicked back button, which will navigate it to the login screen of id server but state will not be set in storage in this case and hence the error when the server redirects back to call back page. Any idea how to mitigate it?

question

All 4 comments

2 ideas: Handle the error, or remove the history entry from the browser.

If it helps, at my company I get developers to do this when receiving the login response, as Brock suggests:

// Handle the response
const user = await this._userManager.signinRedirectCallback();

// Get the hash URL before the redirect
const data = JSON.parse(user.state);

// Replace the browser location, to prevent tokens being available during back navigation
history.replaceState({}, document.title, data.hash);

Also, IIRC, I added a while ago a flag to do this internally (at least on signinRedirect): https://github.com/IdentityModel/oidc-client-js/issues/896

I am not sure how history.replaceState will help (am I missing something?).

The scenario is:

user lands on app page -> page checks user, if not logged in -> signinRedirect to Id server -> Id server redirects back to auth-callback -> auth-callback navigates to some page in app.

Now if user pressed back button which will take it back to the login (where the state (state which is sent to id server) wouldn't be written to local storage which is why siginRedirectCallback throws this error.

However i have seemed to avoid this one using a simple null check on user:

      //user if not null means it is already built 
      if(this.user == null){
        this.user = await this.manager.signinRedirectCallback();
        this._authNavStatusSource.next(this.isAuthenticated());
      }

I hope this is correct and may help if someone else is having same issue.

P.S. Brock rocks!

Was this page helpful?
0 / 5 - 0 ratings