auth0-react: Race condition between isAuthenticated and isLoading (redirects) (react-router-v6)
Hello guys!
We have a application with auth0 and react-router v6 and we stumbled upon something that looks like a race condition with onRedirectCallback
const ProtectedRoute = withAuthenticationRequired(Component, {
onRedirecting: () => <OurLoadingPage />,
loginOptions: {
acr_values: auth0Config.acrValues,
}
});
-----------------------------------------------------------------------------------------------------------
const Auth0Example = ({ props }) => {
const navigate = useNavigate();
const onRedirectCallback = appState => {
navigate(appState?.returnTo || window.location.pathname);
};
return (
<Auth0Provider
{...auth0Config}
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
>
{children}
</Auth0Provider>
)
}
This causes us to have a infinite login loop because isLoading is set to false and isAuthenticated is not yet true. (cookie not yet set)
If we add
const onRedirectCallback = appState => {
setTimeout(navigate(appState?.returnTo || window.location.pathname), 3000);
};
It will work. (this is not a option because we dont want timeouts in our code)
Or if we remove the onRedirectCallback, but then it wont navigate correctly. (get a blank page without the rendering of component)
isLoading TRUE isAuthenticated FALSE
isLoading FALSE isAuthenticated FALSE
isLoading FALSE isAuthenticated TRUE
Should there be a flag that hold the state of a cookie is set or not before redirecting?
also noted here:
https://github.com/auth0/auth0-react/issues/82#issuecomment-672853184
Thanks in advance. And have a lovely day š
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 7
- Comments: 24 (2 by maintainers)
Thanks for providing the example repro @dalecarslaw
I can confirm the issue, when the user returns to the app after login Iām seeing an unexpected state of
isAuthenticated: false , isLoading: false
This looks like itās caused by the new behaviour of React 18 that double invokes things like
setState
in StrictMode to detect unexpected side effects (see https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)This will only happen in development mode, and the workaround for now is to not use
StrictMode
- I can confirm that the example app @dalecarslaw shared works as expected if I remove the<StrictMode>
component here https://github.com/dalecarslaw/auth0-issue/blob/master/src/index.tsx#L12Iāll prepare a fix as soon as I can and update this thread when itās available
My work around is checking the cookie set by auth0 rather than relying on isAuthenticated. I think it causes an extra redirect but it seems to work, at least for my app
Experiencing the same issue where isLoading is false but isAuthenticated is also still false and becomes true after. Iām doing this inside of a useEffect similar to @awdyson
Created a repo using CRA to show example here
Also worth mentioning - this only happens after the redirect. Refreshing the page with a logged in account works as expected.
Initial redirect after logging in with google:
Then after I refresh the page:
I was running into the exact same issue. When I refreshed the page it would always log my user out and this condition would be
true
even though my user was technically supposed to still be logged inThis seems like a major bug
I fixed it by seeing the cacheLocation to localStorage:
Now when I refresh, my user stays logged in and my if statement is no longer ran
I havenāt gotten around to testing if strict mode helps. Will leave myself a reminder for tomorrow morning though!
@adamjmcgrath Canāt believe I forgot to mention this earlier, sorry! My project is on React 17 and react-router v5.
Will test out the prod build, and with(out) strict and update this comment.
I have a similar issue, but I donāt know if this is because react 18 or react-location (we have another app with react 17 and reac-router v5 which works perfectly fine).
So instead of using
withAuthenticationRequired
, I did the following work-around (inspired from above comments - thank you all ^^):Same issue with a
useEffect
approach, and same solution.Hello and thanks for the reply. Will do š
I have a similar case ā along with
onRedirectCallback={(appState) => { navigate(appState?.returnTo || window.location.pathname, { replace: true }); }}
I also have a redirect from root to a protected route (i.e.<Route element={<Navigate replace={true} to={{ pathname: "/hives" }} />} exact={true} path="/" />
) deeper in the components tree within the component that isnāt rendered up untilisLoading
istrue
. However, when the flag indeed becomestrue
and the aforementioned redirect happens, more often than not the user is not authenticated yet, sowithAuthenticationRequired
that protectes the /hives route redirects to the login dialog, from there returns to/?code=...&state=...
, and before auth0-react can authenticate the user theNavigate
to the protected route is being rendered again and, given that the user is not authenticated, it goes to the login dialog again. So it seems like I cannot rely onisLoading
flag as an indication that theuser
has been correctly processed š¤. If I remove the redirect from / to /hives it all works, tho.