Oidc-client-js: InMemoryWebStorage error in 1.8.2

Created on 3 Jul 2019  路  5Comments  路  Source: IdentityModel/oidc-client-js

Hi there, first up a big thanks for this library. It is super helpful. I have been playing around with the client in a very basic react application (no redux) and everything has been working great until today when I decided to try the InMemoryWebStorage for my user store.

Im hoping i'm just missing something simple but when I set:

userStore: new OIDC.InMemoryWebStorage()

When my application starts / loads it gives me an error from oidc-client-min.js which says "TypeError: this._userStore.get is not a function"

I am using version 1.8.2 and my basic code is as follows:

import OIDC from "oidc-client";

const OidcSettings =: {
      authority: "http://localhost:5000",
      client_id: "js",
      response_type: "code",
      scope: "openid profile api1",
      revokeAccessTokenOnSignout: true,
      automaticSilentRenew: true,
      redirect_uri: "http://localhost:3000/signincallback",
      silent_redirect_uri: "http://localhost:3000/silentsignincallback",
      post_logout_redirect_"http://localhost:3000",
      userStore: new OIDC.InMemoryWebStorage()
    }
const userMgr: OIDC.UserManager = new OIDC.UserManager(
    OidcSettings
);

Thanks in advance for any help.

bug

Most helpful comment

@Kevinio04 Hi, i'm also trying to use InMemoryWebStorage but i set it as the store for the WebStorageStateStore

userStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }),
stateStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }),

@brockallen i don't know if it's a bug or i'm using it wrong, but the problem that i have in this case is that when i hit the signinRedirectCallback() after authenticating in the identity provider i get the error Error: No matching state found in storage

All 5 comments

So funny thing -- as I was reading this, I was thinking "I've never heard of this InMemoryWebStorage before". Turns out I wrote it (I guess), but I had forgotten about it. Comparing it to the WebStorageStateStore they are not implementing the same interface. So that explains it. I guess I never intended for InMemoryWebStorage to ever really be used. Either that, or I have amnesia.

Haha, that made me chuckle. In which case I should probably not be using it.

I thought I would see how it worked after reading issue / comments on item #830 - it seemed like it was something that was going to be added to the documentation.and I was just curious

@Kevinio04 Hi, i'm also trying to use InMemoryWebStorage but i set it as the store for the WebStorageStateStore

userStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }),
stateStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }),

@brockallen i don't know if it's a bug or i'm using it wrong, but the problem that i have in this case is that when i hit the signinRedirectCallback() after authenticating in the identity provider i get the error Error: No matching state found in storage

@tomthebearded try setting only the userStore , not the stateStore.

I believe the stateStore must persist across pageloads because it needs to put in before the auth redirect and then grab it out after the callback. Then it removes it from local storage and your user info, access token etc is stored 'in memory'.

Works for me anyway. Thanks for posting how to use the InMemoryWebStorage, couldn't find this anywhere.

@tomthebearded Thanks for showing how to use InMemoryWebStorage.

Regarding signinRedirectCallback, I think that's only expected to work when someone was redirected from the identity server into your application. They'll end up at your post_logout_redirect_url with a token in the Fragment Identifier (i.e. "#id_token=..."). If this token is present, signinRedirectCallback should work. Otherwise, it won't.

We basically accept that behavior as part of our workflow, like this:

private async tryToSignIn(manager: UserManager) {
    try {
        // If the user was just redirected here from the sign in page, sign them in.
        await manager.signinRedirectCallback();
        console.debug("User was redirected here via the sign-in page. They are now signed in.");
    } catch (error) {
        console.debug("Sign-in redirect callback doesn't work. Let's try a silent sign-in.", error);
        // Barring that, if the user chose to have the Identity Server remember their
        // credentials and permission decisions, we may be able to silently sign them
        // back in via a background iframe.
        await manager.signinSilent();
        console.debug("Silent sign-in completed.");
    }
}

I'm not a big fan of using try/catch in the ordinary app workflow, but I don't think there's any API call to detect whether the signInRedirectCallback() _would_ work, and I don't want to rely on implementation details like checking the URL for a token in the URL Fragment.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StephenRedd picture StephenRedd  路  5Comments

rmja picture rmja  路  3Comments

iXmonvi33 picture iXmonvi33  路  4Comments

eckersalld picture eckersalld  路  5Comments

LEW21 picture LEW21  路  4Comments