oidc-client
oidc-client copied to clipboard
Sessions lost/timed out when using multiple browser tabs
Issue and Steps to Reproduce
In a multiple tabbed scenario for the same SPA application, sessions are not being renewed correctly.
I have tried switching the token storage to local as a workaround but the issue persists.
I've also looked at ignoring the session lost event or adding a redirect/reload but no luck.
Versions
6.16.9
Screenshots
Expected
Sessions should be renewed across all tabs silently
Actual
Sessions are expiring - storage shows one of the following for the oidc.default key:
{"tokens":null,"status":null} {"tokens":null,"status":"LOGGED_OUT"}
If using session storage, the following is shown:
{"tokens":null,"status":"SESSION_LOST"}
Additional Details
The web worker doesn't seem to be registered - not sure if this is relevant here but thought I'd mention it!
Hi @cattre ,
Thank you for your issue. Do you have a sample of you configuration?
Hi @guillaume-chervet,
Thanks for the quick reply (and for the library, which is great!).
I've got it working now, but only after downgrading to v6.14.8 - does this help at all? Let me know what other config you need to see.
Also, is local storage the only option for this use case?
Hi @cattre , it should works with localstorage or with serviceworker mode.
Do you use service worker ?
Hi @guillaume-chervet, we have the service worker files but it doesn't look it's being used (nothing showing as registered in dev tools).
I think for our requirements (accessing the token within js), localstorage is probably the best option so we'll still with that for now. Do you know any reason for this not to work in the latest version though?
Hi @cattre do you have a sample of your configuration. It will help me to help you more.
@guillaume-chervet I can't share the whole app but these are the main parts I guess:
export const IDENTITY_CONFIG = {
authority: rootPath,
client_id: clientId,
redirect_uri: rootPath + basePath + '/signin-oidc',
silent_redirect_uri: rootPath + basePath + '/silent-renew',
scope: 'openid offline_access',
automaticSilentRenew: true,
storage: localStorage
}
<OidcProvider configuration={IDENTITY_CONFIG}
loadingComponent={Loading}
authenticatingErrorComponent={AuthError}
authenticatingComponent={Loading}
callbackSuccessComponent={Loading}
>
<App />
</OidcProvider>
Hi @cattre ,
I cannot reproduce your issue copying the your configuration using the demo. Does your oidc server is inside the same domain than your application?
If you use your configuration with the demo. https://black-rock-0dc6b0d03.1.azurestaticapps.net/ May you send me the logs? in order to understand what happenning?
I am able to reproduce this.
Create a new React app, and install this library
npx create-react-app --template cra-template-typescript .
npm install --save @axa-fr/react-oidc
Then modify src/index.tsx
:
diff --git a/src/index.tsx b/src/index.tsx
index 032464f..e00635d 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
+import { OidcProvider, OidcSecure } from '@axa-fr/react-oidc';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
@@ -7,9 +8,23 @@ import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
+const configuration = {
+ authority: 'https://auth.example.com',
+ client_id: 'client-id',
+ redirect_uri: `${window.location.origin}/authentication/callback`,
+ silent_redirect_uri: `${window.location.origin}/authentication/silent-callback`,
+ scope: 'openid',
+};
root.render(
<React.StrictMode>
- <App />
+ <OidcProvider
+ configuration={configuration}
+ onEvent={(name, data) => console.log({ name, data }, 'OidcProvider event')}
+ >
+ <OidcSecure>
+ <p>Hello, world</p>
+ </OidcSecure>
+ </OidcProvider>
</React.StrictMode>
);
Run npm run start
, and open a second tab to the same location. After the first access token expires, the first tab should show the session lost component.
Additionally, the console log shows:
Object { name: "default", data: "refreshTokensAsync" }
OidcProvider event index.tsx:22
Object { name: "default", data: "refreshTokensAsync_begin" }
OidcProvider event index.tsx:22
Object { name: "default", data: "refreshTokensAsync_error" }
OidcProvider event index.tsx:22
In case it matters, I am using Keycloak 20.0.1 as my IdP. I observed the same behavior in Firefox 110.0.1 and Chromium 111.0.5563.146.
Hi @jasonaowen , very sorry i missed you message. I will try to reproduce it quickly so i will be able to fix it.
Thank you, @guillaume-chervet! No apology needed; I appreciate you maintaining this wonderful tool.
Hi @jasonaowen @richcatt , i set the same configuration on the demo using dudende oidc server and i cannot reproduce the error. Which oidc server are you using?
@guillaume-chervet I am using Keycloak, but I was also able to reproduce it with the demo Duende server:
@@ -7,9 +8,23 @@ import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
+const configuration = {
+ authority: 'https://demo.duendesoftware.com/',
+ client_id: 'interactive.public.short',
+ redirect_uri: `${window.location.origin}/authentication/callback`,
+ silent_redirect_uri: `${window.location.origin}/authentication/silent-callback`,
+ scope: 'openid',
+};
root.render(
<React.StrictMode>
- <App />
+ <OidcProvider
+ configuration={configuration}
+ onEvent={(name, data) => console.log({ name, data }, 'OidcProvider event')}
+ >
+ <OidcSecure>
+ <p>Hello, world</p>
+ </OidcSecure>
+ </OidcProvider>
</React.StrictMode>
);
Interestingly, while I can still reproduce this on Firefox 112.0, I can no longer reproduce it in Chromium 112.0.5615.49. Unfortunately, the Chrome change log for that version range is a bit overwhelming, and I am not currently set up to install specific commits or even older versions to figure out what changed.