Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question on implementation approach #201

Open
2 tasks
tantilla opened this issue Jan 27, 2022 · 7 comments
Open
2 tasks

Question on implementation approach #201

tantilla opened this issue Jan 27, 2022 · 7 comments

Comments

@tantilla
Copy link

I'm submitting a:

  • Bug report
  • Feature request
  • [ *] Other (Describe below)
    Question

Current behavior

Expected behavior

Minimal reproduction of the problem with instructions

Extra information about the use case/user story you are trying to implement

Environment

  • Package version:
  • React version:
  • Browser:
  • OS:
  • Node version (node -v):
  • Other:

Configuration

  • Okta application type: React / web

Hello,
Sorry for posting a question here, not getting responses in the forum.

I’m using a typical PKCE hosted login setup based on the okta-react hosted login demo, initialized once at the top of the app with a switch and secure routes.

“@okta/okta-auth-js”: “~5.10.1”,
“@okta/okta-react”: “~6.4.1”

For the most part everything is working as as expected, but a few times a month users (oddly only in the east coast region) get redirected to the login page from their secure route, interrupting their work session. I implemented an error component expecting to log evidence of some session issue there but so far the users have not reported error screens. Htttp archive files just show intermittent redirects to the hosted login.

Our users now want a guarantee that they can perform some actions before they are redirected, like a warning dialog with local storage save options - regardless of whether the redirect is triggered by standard session expiration or some exception in the core library.

Without having yet examined the okta-react or okta-auth-js source, is there a supported / recommended approach to add some kind of redirect guard, or is the window location being manipulated somewhere without options so the redirect cannot be blocked by anything via API, in which case implementing a custom component wrapping the core library would be necessary ?

@jaredperreault-okta
Copy link
Contributor

@tantilla do you happen to know if the users experiencing these issues are using multiple tabs?

@tantilla
Copy link
Author

Yes they are nearly always using multiple tabs.

@jaredperreault-okta
Copy link
Contributor

We are currently investigating an intermittent issue when users have multiple tabs open simultaneously. The scenario you described seems to match. Could you provide a minimum code sample or git repo which reproduces the issue so we can confirm?

@tantilla
Copy link
Author

To be clear, I have not been able to reproduce the issue personally, even after leaving the application open all day. Its only via user's videos and logs that I've seen any evidence of issues. I am beggining to collect browser information. At any rate, though I doubt it's helpful, below is the basic auth pattern we use in all our applications.

If you think only instantiating one running core Okta-js instance, instead of one in every tab, would improve session stability, perhaps deriving a secondary auth API for new tabs, that just queries the tokens, etc. set in storage by the singleton auth instance in the main application might be a reasonable approach...

import { OktaAuth, toRelativeUrl } from '@okta/okta-auth-js';
import { LoginCallback, SecureRoute, Security, useOktaAuth } from '@okta/okta-react';
import { history } from 'core';
import React, { useEffect, useState } from 'react';
import { Route, Router, Switch } from 'react-router-dom';

const { REACT_APP_ISSUER, REACT_APP_CLIENT_ID } = process.env
if (!REACT_APP_ISSUER || !REACT_APP_CLIENT_ID) {
  throw `Missing Okta Configuration`;
}
const okta = new OktaAuth({
  issuer: REACT_APP_ISSUER,
  clientId: REACT_APP_CLIENT_ID,
  redirectUri: window.location.origin + '/login/callback',
  pkce: true,
  tokenManager: {
    autoRenew: true
  }
});

okta.authStateManager.subscribe((a: any) => {
  console.log('State change accessToken)', a.accessToken?.accessToken);
});
okta.tokenManager.on('expired', (key, expiredToken) => {
  console.log('Token with key', key, ' has expired:', expiredToken);
});
okta.tokenManager.on('renewed', function (key, newToken, oldToken) {
  console.log('Token with key', key, 'has been renewed', oldToken, newToken);
});
okta.tokenManager.on('error', function (err) {
  console.log('TokenManager error:', err);
});

const Home = () => {
  const { authState, oktaAuth } = useOktaAuth();
  const [userInfo, setUserInfo] = useState(null);

  useEffect(() => {
    if (!authState || !authState.isAuthenticated) {
      setUserInfo(null);
    } else {
      oktaAuth.getUser().then((info) => {
        setUserInfo(info);
      }).catch((err) => {
        console.error(err);
      });
    }
  }, [authState, oktaAuth]); // Update if authState changes

  const login = async () => {
    oktaAuth.signInWithRedirect({ originalUri: '/' });
  };

  useEffect(() => {
    if (!authState?.isAuthenticated) {
      login()
    }
  }, [])

  if (!authState) {
    return (
      <div>Loading...</div>
    );
  }

  return (
    <div >
      <div>
        {authState?.isAuthenticated &&
          <p>
            <a href='/admin'>To Admin</a>
          </p>
        }

        <div>
          User
          <p>
            {
              <div style={{ width: '70vw', whiteSpace: 'pre-wrap', fontSize: 9, wordWrap: 'break-word' }}>{JSON.stringify(userInfo || {}, null, 1)}</div>
            }
          </p>

        </div>

        <div>
          Auth State
          <p>
            {
              <div style={{ width: '70vw', whiteSpace: 'pre-wrap', fontSize: 9, wordWrap: 'break-word' }}>{JSON.stringify(authState || {}, null, 1)}</div>
            }
          </p>
        </div>
      </div>
    </div>
  );
};

function App() {
  const restoreOriginalUri = async (_oktaAuth: any, originalUri: any) => {
    history.replace(toRelativeUrl(originalUri || '/', window.location.origin));
  };

  return (
    <Security oktaAuth={okta} restoreOriginalUri={restoreOriginalUri}>
      <Router history={history}>
        <Switch>
          <Route path='/' exact component={Home} />
          <Route path='/login/callback' exact component={LoginCallback} />
          <SecureRoute path='/admin' exact>
            Admin
          </SecureRoute>
        </Switch>
      </Router>
    </Security>
  )
}
export default App;

@chinanderm
Copy link

I've been encountering this same thing for over a year now. Not using multiple tabs. Just all of a sudden, me and other users get kicked to the login page for seemingly no reason.

@jwmke
Copy link

jwmke commented Mar 27, 2024

hi @chinanderm

Did you ever find out what was causing this issue? I'm also not using multiple tabs and am experiencing the same issue.

@chinanderm
Copy link

@jwmke Unfortunately no. I moved away from using the Okta React library and am using their raw JS library instead, building the functionality I need myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants