okta / okta-auth-js

The official js wrapper around Okta's auth API
Other
437 stars 255 forks source link

TokenManager.emitAdded() called multiple times on tab duplication #1492

Open gchacon-bwi opened 5 months ago

gchacon-bwi commented 5 months ago

Describe the bug

We are experiencing problems fetching the logged user info in our SPA, in which we are detecting a burst of multiple calls when the token expires.

We are implementing Okta in a React 18 SPA:

"@okta/okta-auth-js": "^7.5.0",
"@okta/okta-react": "^6.7.0",

After starting to check where the issue was coming from we were able to identify that transformAuthState (implemented in our Okta config) was called multiple times soon as token expired, this made us think something SPA architecture was re render multiple times making the TokenManager to update multiple times, but we confirmed our instantiation was a single instance and wasn't the one to blame.

After starting to check where the issue was coming from, we were able to identify that transformAuthState (implemented in our Okta config) was called multiple times as soon as the token expired. This made us think something in the SPA architecture was re-rendering multiple times, making the TokenManager to update multiple times, but we confirmed our instantiation was a single instance and wasn't the one to blame.

If we kept only one tab open, we got a consistent single console.trace printed, as you might expect when a token expires and we update with a new one; however, we noticed that as we duplicated the open tab, it seems in the already opened tab Okta-auth-js is subscribing again to the same event. As you keep opening tabs, the already-opening tabs get more exponential subscriptions to the same event over and over. By the time the token expires, this triggers a burst of multiple calls from the various subscriptions across all tabs, resulting in a call limit for the API. As a result, all tabs are unable to get a response, and the app gets stuck.

Attached to this report, I'm adding a screenshot of the logs we get. We are adding the time and attaching it to the contsole.trace, notice in the screenshot the times, you will see multiple calls happening in the exact same second.

Screenshot from 2024-02-06 15-55-36

Here also another screenshot from the network tab where can be seen multiple calls to token and to fetch the userInfo Screenshot 2024-02-06 at 11 43 27 AM

This is our Okta setup:

const oktaAuth = new OktaAuth({
  redirectUri: urlJoin(modifiedBasePath, "/", "okta/callback"),
  postLogoutRedirectUri: urlJoin(modifiedBasePath, "/", "loggedOut"),
  scopes: ["openid", "profile", "email"],
  pkce: true,
  disableHttpsCheck: true,
  cookies: {
    secure: true,
  },
  storageManager: {
    token: {
      storageTypes: ['sessionStorage'],
    },
  },
  {
    transformAuthState: async (oa, authState) => {
      console.trace((new Date()).toISOString(), 'transformAuthState', authState);
      return authState;
    }
  },
  ...CONFIG.passport.oidc // This includes our client id and issuer
});

Worth mentioning:  - In this example, we have also cleaned all the logic in the transformAuthState with just a console.trace to remove all possible elements from the equation.  - This is set in the main index.js outside any react scope (just in case).

We have tried updating this by removing cookies and strorageManager config, but the behaviour persists, with the difference that it is stored in the localStorage instead.

From our tests, we can confirm that:  - The issue seems to happen in any Browser. We have experienced this in (Chrome, Firefox and Brave).  - The issue is worst in IOs compared to Linux. Those devs using MacBook have more logs printed than Linux users. When rolling back to the localStorage config in Linux we start to get a consistent 4 calls per tabs, still a lot anyway.

Reproduction Steps?

After token expires your first tab should have multiple console.trace printed compared to the last one (the more tabs opened the more subscriptions you get in the already opened tab).

SDK Versions

Machine 1: System: OS: Linux 5.14 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish) CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz Memory: 1.94 GB / 31.09 GB Container: Yes Shell: 5.1.16 - /bin/bash Binaries: Node: 14.17.0 - ~/.nvm/versions/node/v14.17.0/bin/node Yarn: 1.9.0-20180719.1538 - /usr/bin/yarn npm: 6.14.13 - ~/.nvm/versions/node/v14.17.0/bin/npm Browsers: Brave Browser: 121.1.62.156 Chrome: 121.0.6167.139 npmPackages: @okta/okta-auth-js: ^7.5.0 => 7.5.0 @okta/okta-react: ^6.7.0 => 6.7.0

Machine 2: System: OS: macOS 14.2.1 CPU: (10) arm64 Apple M1 Pro Memory: 69.25 MB / 32.00 GB Shell: 5.1.16 - /opt/homebrew/bin/bash Binaries: Node: 16.18.1 - ~/.nvm/versions/node/v16.18.1/bin/node Yarn: 1.22.21 - ~/.nvm/versions/node/v16.18.1/bin/yarn npm: 8.19.2 - ~/.nvm/versions/node/v16.18.1/bin/npm Browsers: Chrome: 121.0.6167.139 Safari: 17.2.1 npmPackages: @okta/okta-auth-js: ^7.5.0 => 7.5.0 @okta/okta-react: ^6.7.0 => 6.7.0

Additional Information?

No response

jaredperreault-okta commented 4 months ago

@gchacon-bwi I haven't been able to reproduce what you're experiencing, would you be able to make a repo that demonstrates this behavior?

During my testing I saw the same amount of transform calls, independent of the # of tabs