Okta React SSO, multiple Apps using the same custom login page

I’m using Okta to manage the users of my application (PKCE enabled since it’s a web app), which is made in React.
I implemented a custom login page with is working fine and authenticating the user. One of the requisites of the App is that when a user is already authenticated in the Okta domain (ex. account.mycompany.com) the user must not have to authenticate in this app again. It should keep the authentication. I’m using this Okta package in my project

I managed to do that and when the user is already authenticated in the Okta domain the app loads his authentication and continues the flow. The problem is that when the user is not authenticated it’s sending the user to the okta hosted login page. I need it to send to mine.

Below is the code of my React app. In the comment the line where this is done which is where I would like to know what to change to have the expected behavior.

const MyApp = () => {
  const defaultTheme = useTheme();
  const theme = createTheme(deepmerge(defaultTheme, MainTheme));
  const navigate = useNavigate();
  const oktaAuth = new OktaAuth(getOktaConfig());

  const triggerLogin = async () => {
    // this is the line that handles the user already authenticated 
    // and also the line that is sending the user to the okta hosted login page.
    // What do I change so it continues to authenticate the user when he's already 
    // authenticated in the domain but also it doesn't send him to the okta hosted login page?
    await oktaAuth.signInWithRedirect();
  };

  const onAuthRequired = async () => {
    const previousAuthState = oktaAuth.authStateManager.getPreviousAuthState();
    if (!previousAuthState || !previousAuthState.isAuthenticated) {
      // App initialization stage
      await triggerLogin();
    } else {
      // Ask the user to trigger the login process during token autoRenew process
      navigate(routes.SIGN_IN().PATH, { replace: true });
    }
  };

  const restoreOriginalUri = async () => {
    navigate(routes.DASHBOARD().PATH, { replace: true });
  };

  return (
    <Security
      oktaAuth={oktaAuth}
      onAuthRequired={onAuthRequired}
      restoreOriginalUri={restoreOriginalUri}
    >
      <Provider store={store}>
        <AppProviders>
          <LayoutWrapper>
            <ThemeProvider theme={theme}>
              <Router />
            </ThemeProvider>
          </LayoutWrapper>
        </AppProviders>
      </Provider>
    </Security>
  );
};

I have already tried to pass the original uri in the signInWithRedirect method.

await oktaAuth.signInWithRedirect( { originalUri:routes.SIGN_IN().PATH });

I also tried the answer of this post

And it didnt give me the behavior I need. I feel like I need a way to inform Okta, via code or a configuration, the url of the login page to redirect the user to when he’s not authenticated. Not sure if it’s possible though.

Thanks for any help

Hello Andre,

Typically there are two ways to do this.

  1. If your SPA application is running in the same domain as your Okta domain (assuming you are using a custom domain URL in your Okta Org), then you can use the sessions API in auth-js. Using this API you can check if a session exists and only do an /authorize call if so. The reason you need to run in the same domain/parent domain is the API relies on 3rd party cookies.
  2. Do an /authorize call as you currently are but provide the param prompt=none. This will cause Okta to redirect the user back to the redirectURI if a session does not exist which you can handle by presenting your custom login page.

Thank You,

1 Like

Hi Erik,
Thanks for the reply.

As you said, third-party cookies are important. I was testing in incognito and chrome comes with this option selected by default “Block third-party cookies in Incognito”, which was preventing the flow to work properly.

Since I’ve seen this same question on many places on the internet I’m pasting below the piece of code that made it work in my React App.

useEffect(() => {
    if (oktaAuth.authStateManager.getAuthState()?.isAuthenticated) {
      navigate(routes.DASHBOARD().PATH, { replace: true });
    } else {
      oktaAuth.session.exists().then((exists) => {
        if (exists) {
          oktaAuth.token
            .getWithoutPrompt({
              responseType: ['token', 'id_token'],
            })
            .then((res) => {
              oktaAuth.handleLoginRedirect(res.tokens);
            });
        }
      });
    }
  }, [isAuthenticated]);

Thanks

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.