Okta Sign-In Widget Bypass - React

I am developing a feature which uses the same Okta session but on two different domains. I login to Okta on one domain, an iframe to another domain loads where a user would be prompted for their Okta login using the Okta Sign-In Widget. I want to bypass the sign in on the second domain and I am able to do that by using postMessage to the iframe with the first domain’s okta tokens and then receiving them on the login page of the second domain.

On the login page, I listen for the message from the first domain, and then use oktaAuth.tokenManager.setTokens(tokens) to set the tokens in the iframe. The problem is, once I set the Okta tokens, I want to redirect the user to a separate page. I do this with react-router-dom’s useHistory push(path) method. Doing this after setting the tokens gives me the following error:

TypeError: Cannot read property 'remove' of undefined

I get this because when the Login component unmounts, I remove the widget using widget.remove(). After looking around, I found the cause of this to be because I am attempting to remove the widget before it has fully rendered and therefore when widget.remove() is run, portions of it are not declared and are undefined.

A solution to this is to add a timeout around the history.push()

setTimeout(() => {
}, 100);

but I don’t like this solution. I have also tried performing this path change in an oktaAuth.authStateManager.subscribe() method, but that too is called too quickly and a timeout would still be needed.

Has anyone come across this before or has any recommendations I can try? I am using React, react-router-dom, okta-react, and okta-signin-widget. Thanks!

In case anyone finds this and is curious, I was able to remove the need for a timeout by sending a message from the iframe up to the parent once the login component was ready. Then in the parent, I wait for that message from the iframe before sending the tokens down. Doing this gave enough time for the okta-signin-widget to load enough to accept the tokens, redirect, and remove properly.

I have done a similar method of session sharing between apps on different domains with a post message. This is not a fully tested and NOT supported mechanism however, but could be used as a reference. It would not require using the widget on the receiving page.

In your case would it be possible to do the redirect from the Widget’s after render callback. Perhaps you could have a couple of flags (tokensStored and rendered). If after storing the tokens you check rendered, if true, redirect, if not set tokensStored. In the afterRendered you check tokensStored, if true redirect, otherwise set rendered true. Not sure this would work in your scenario?