keycloakify / oidc-spa

Openid connect client for Single Page Applications
https://www.oidc-spa.dev
MIT License
50 stars 6 forks source link

How to configure the library with microfrontends? #32

Open alanmatiasdev opened 4 days ago

alanmatiasdev commented 4 days ago

I have a set of micro frontends divided into a single page layout: header, content. It turns out that, in general, the platform displays the header and content at once. Since I need user information in both contexts, I include the library for both applications. This causes the library to create different states in the browser's local storage and when opening a new browser tab I get the message that no state was found in the browser. Is there any guidance for this scenario?

OIDC initialization error of type "unknown": No matching state found in storage

garronej commented 4 days ago

Hello @alanmatiasdev,

I know that we use oidc-spa at Insee in microfronted setups but I never used microfronted myself.
If you produce a simple repo with a readme that explains what you expect and what isn't working as you expect I can have a look at it.

alanmatiasdev commented 4 days ago

I made this small project to try to exemplify the issue, but I couldn't reproduce the error that is notified, however, it reproduces the issue of multiple states in local storage (is this expected behavior?). This project simulates an application of a real case that I have. If you try to run it and encounter any difficulties, please let me know.

https://github.com/alanmatiasdev/react-mfr-oidc-example

image

I'm trying to reproduce the initial behavior: when opening a new tab, it apparently can't read the state of the local storage and returns the error above.

Update: I noticed that when opening a new tab, it searches for a state that does not exist in the local storage and this gives me the error mentioned above.

alanmatiasdev commented 3 days ago

@garronej I managed to resolve the issue of the error mentioned above (regarding opening new tabs) by changing the userStore from sessionStorage to localStorage. I made the change because sessionStorage does not share stored data between tabs even if a new tab is from the same source. Would this be a bad practice in any way or can we implement this possibility in the library?

image

https://github.com/keycloakify/oidc-spa/blob/a06808eb695f6537cb1716459a9594dfd2e0875b/src/oidc.ts#L363-L388

However the multiple states still remain and I believe it is related to having multiple instances of the lib on the page.

garronej commented 3 days ago

First off, thank you for taking the time to investigate this so thoroughly.

Would this be a bad practice in any way, or can we implement this possibility in the library?

Unfortunately, this isn’t ideal. The whole point of opening an iframe in the background and getting the auth server to redirect to silent-sso.htm is to avoid relying on localStorage and instead use HTTP-only cookies. If you use localStorage, your app won’t pass a security audit.

Just to make sure we’re on the same page: I don’t believe there’s a known issue here, as we can restore the session using silent SSO. Can you confirm that you’re unable to reproduce any issues or suspicious behavior with the demo apps, like the TanStack Router demo app?

However, the multiple states still remain, and I believe it is related to having multiple instances of the lib on the page.

That’s concerning. You should have at most two session storage entries—something isn’t behaving as expected.

I had some trouble running your demo repo:

image

Could you update it to use my public Keycloak instance, which I use for my test project? You can check out the example here:
https://github.com/keycloakify/oidc-spa/blob/main/examples/tanstack-router-file-based/.env.local.sample

This would make it easier for me, so we don’t have to spin up a Keycloak Docker container for testing, and we can rule out any issue related to a specific Keycloak configuration.

I don’t have much experience with microfrontends, but my colleague @ddecrulle is quite knowledgeable in that area. If you can set up a straightforward reproduction path, there’s a good chance we’ll be able to figure it out.

By the way, what brought you to this library? I’m curious since it still has a relatively small user base, and I’d love to know what convinced you to give it a try.

alanmatiasdev commented 3 days ago

Just to make sure we're on the same page: I don't believe there's a known issue here, as we can restore the session using silent SSO. Can you confirm that you’re unable to reproduce any issues or suspicious behavior with the demo apps, like the TanStack Router demo app?

I will test and return with feedback.

Could you update it to use my public Keycloak instance, which I use for my test project? You can check out the example here: https://github.com/keycloakify/oidc-spa/blob/main/examples/tanstack-router-file-based/.env.local.sample

Yes, of course. I updated the repository https://github.com/alanmatiasdev/react-mfr-oidc-example

By the way, what brought you to this library? I’m curious since it still has a relatively small user base, and I’d love to know what convinced you to give it a try.

I have been using Keycloakify for some time now, since implementing oidc-spa. I tested it in a development environment and, based on my analysis, I found the library to be more stable than the implementation we had. I chose to adopt it due to its simplicity of implementation.

alanmatiasdev commented 3 days ago

Just to make sure we're on the same page: I don't believe there's a known issue here, as we can restore the session using silent SSO. Can you confirm that you’re unable to reproduce any issues or suspicious behavior with the demo apps, like the TanStack Router demo app?

It is working correctly. I believe this has something to do with the microfrontends configuration.

ddecrulle commented 3 days ago

Thanks for the report, I'm having the same issue as @garronej :

image

alanmatiasdev commented 2 days ago

Strange. Did you run yarn start from the root of the project? Are all applications running correctly? Can you verify that localhost:5173/src/spa.tsx returns a vite build code?

image

ddecrulle commented 1 day ago

The issue occurred because I had something running on port 5173, and the monorepo doesn’t handle port changes well.I can reproduce now.

garronej commented 1 day ago

Can you guys give a try with 5.3.0-rc.1 ?

alanmatiasdev commented 1 day ago

Unfortunately, this isn’t ideal. The whole point of opening an iframe in the background and getting the auth server to redirect to silent-sso.htm is to avoid relying on localStorage and instead use HTTP-only cookies. If you use localStorage, your app won’t pass a security audit.

Could we include the possibility for the user to change the storage, perhaps marking it as unsafe?

Can you guys give a try with 5.3.0-rc.1 ?

I will try and get back to you.