react-oidc-context icon indicating copy to clipboard operation
react-oidc-context copied to clipboard

Authentication is not working after upgrading to react 18

Open VijayaSaiRam opened this issue 1 year ago • 7 comments

I have upgraded to React 18. after that when I load the page, it is not coming out of the loading spinner, authentication is not working. const root = createRoot(document.getElementById('root')); root.render( <React.StrictMode> <AuthProvider {...oidcConfig} > <Provider store={store}> <BrowserRouter> <App /> </BrowserRouter> </Provider> </AuthProvider> </React.StrictMode> ); If I comment <React.StrictMode> then it is working could you please help me on this

Thankyou. Regards, Vijaya

VijayaSaiRam avatar Jun 05 '24 04:06 VijayaSaiRam

@VijayaSaiRam - can confirm that this library works okay with react 18. See:

https://github.com/authts/sample-keycloak-react-oidc-context/blob/079d739d46521693d55a869e1e0d7109edcf81b8/react/package.json#L19-L20

Your issue may be elsewhere, but it's hard to tell from the snippet you provided.

Can you provide a minimal reproducible example?

zach-betz-hln avatar Jun 05 '24 15:06 zach-betz-hln

I have upgraded to "react": "^18.3.1", "react-dom": "^18.3.1",

and to fix the warning [Deprecation notice: ReactDOM.render is no longer supported in React 18]

I have changed code in index.js to as follows. import React, {StrictMode} from 'react'; import ReactDOM from 'react-dom'; import { createRoot } from 'react-dom/client'; image

After that authentication is not progressing further.

it is always in the sprinner loading

It is just getting the access code, after that token call is not happening, it always stays in the following code useEffect(() => { if (!auth.isAuthenticated && !auth.error && !auth.isLoading) { auth.signinRedirect(); } if (auth.error) { authenticaionFailed(); } if (auth.isAuthenticated && auth.user) { authenticationPassed(auth.user); } auth.events.addSilentRenewError(error => { if (AUTH_MESSAGES.indexOf(error.message) !== -1) { setShowTimeoutModal(true); } else { authenticaionFailed(error); } }); if (!authenticating && userInfo) { if (scopes.length < 1) { navigate(ERROR_PAGES.noAccessError.path); } else if (//custom condition) { // execute else if block } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [authenticating, auth.isAuthenticated, auth.error, auth.isLoading, auth.user]);

If I comment <StrictMode> it is working..

Even if I don't fix the warning [Deprecation notice: ReactDOM.render is no longer supported in React 18] and leave the code as such image

then it is working.

VijayaSaiRam avatar Jun 06 '24 05:06 VijayaSaiRam

After that authentication is not progressing further. it is always in the sprinner loading

Is this "spinner" from Keycloak, or from your React app?

If it's from your React app, what is the code that toggles this spinner?

zach-betz-hln avatar Jun 06 '24 13:06 zach-betz-hln

Hi,

I stumbled upon the same issue but with oidc-client-ts.

I moved the Provider above the StrictMode and now it works. Found this issue as well: https://github.com/react-keycloak/react-keycloak/issues/182

Funny thing is, this only happened with Firefox for me. Chrome works fine without doing the workaround.

Skezzowski avatar Nov 13 '24 15:11 Skezzowski

Hi @Skezzowski - the sample repo uses react 18.x in strict mode and works fine.

Are you able to reproduce your issue there?

zach-betz-hln avatar Nov 13 '24 15:11 zach-betz-hln

@zach-betz-hln: I can reproduce the issue on Firefox. It seems to be due to the fact the StrictMode runs useEffect twice, which aborts the navigation, which causes as NS_BINDING_ABORTED error in Firefox.

The underlying issue seems to be in the way the oidc-client-ts library does the redirect, though I haven't quite figured that part out yet. I don't have the error when running signinRedirect in an onClick event handler in a button -- just when running it in a React hook in strict mode.

Chrome and webkit work fine. One ugly work-around right now for me is to get the user to click a button in my signin workflow component, like so:

import { useAuth } from 'react-oidc-context';
import { useEffect } from 'react';

const Signin = () => {
  const auth = useAuth();

  useEffect(() => {
      auth.signinRedirect();
    }
  , []);

    return <>
        <p>Some browsers (Firefox, mostly) can't handle redirects correctly</p>
        <button onClick={() => {
          auth.signinRedirect();
        }}>Try again</button>
    </>
    ;
};
export default Signin;

Obviously hackish and it means my automated tests in Playwright actually have to know what browser they're running in, but it does work with a little help from the user.

blytkerchan avatar May 10 '25 18:05 blytkerchan

It seems to be due to the fact the StrictMode runs useEffect twice, which aborts the navigation, which causes as NS_BINDING_ABORTED error in Firefox.

StrictMode runs useEffect twice only in development mode. The guard didInitialize in this library should prevent this from happening.

pamapa avatar May 12 '25 09:05 pamapa