Same issue. It worked in my boss’s Chrome browser but not my browser.
I think it has something to do with Chrome phasing-out Third Party Cookies.
Current situation:
- Local env:
- it works differently for different machines:
- My main machine requires re-login every time I refresh the browser. This is causing a lot of pain in development
- Another machine doesn’t have this issue, but it’s much slower.
- Staging:
- SSO doesn’t work in some browsers - i.e. users are logged in on
a.platform.com
but when they click to b.platform.com
, getAccessTokenSilently
failed with login_required
- I think I can just set a custom domain to bypass the 3rd-party cookie but I haven’t been able to verify it yet
Frontend implementation details:
I’m using react-router for navigation, more specifically:
<RouterProvider router={router} />
so for the onRedirectCallback
to redirect, I need to put my Auth0Provider in every route:
import { AppState, Auth0Provider, AuthorizationParams } from '@auth0/auth0-react';
import { Container, Title } from '@mantine/core';
import { ReactNode, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
const domain = import.meta.env.VITE_AUTH0_DOMAIN;
const clientId = import.meta.env.VITE_AUTH0_CLIENT_ID;
export default ({ children }: { children: ReactNode }) => {
const { i18n } = useTranslation(['common']);
const navigate = useNavigate();
const authorizationParams = useMemo(() => {
return {
audience: import.meta.env.VITE_AUTH0_AUDIENCE,
redirect_uri: import.meta.env.VITE_AUTH0_CALLBACK_URL,
ui_locales: i18n.language,
} satisfies AuthorizationParams;
}, [i18n.language, document.cookie]);
const onRedirectCallback = useCallback(
(appState?: AppState) => {
console.log(appState);
navigate(appState?.returnTo || window.location.pathname);
},
[navigate]
);
if (!(domain && clientId && authorizationParams.redirect_uri && authorizationParams.audience)) {
return (
<Container sx={{ paddingBlock: 2, flex: 1, overflow: 'auto' }}>
<Title order={2} color="red.6">
Please fill in all variables
</Title>
</Container>
);
}
// doesn't update Auth0 language upon ui language change, likely issue with Auth0Provider
return (
<Auth0Provider
domain={domain}
clientId={clientId}
authorizationParams={authorizationParams}
onRedirectCallback={onRedirectCallback}
>
{children}
</Auth0Provider>
);
};
Code for getting the user:
const { isLoading, getAccessTokenSilently, loginWithRedirect, user: auth0User, error } = useAuth0();
useEffect(() => {
getAccessTokenSilently()
.then((token) => {
setToken(token);
if (!token) setIsLoadingUser(false);
})
.catch((e) => {
if (!!e && typeof e === 'object' && 'error' in e && e.error) {
console.log(e.error);
if (e.error === 'login_required' || e.error === 'consent_required') {
loginWithRedirect({
appState: {
returnTo: '/',
},
authorizationParams: {
prompt: 'login',
},
});
}
}
setIsLoadingUser(false);
});
}, [setToken, setIsLoadingUser]);
Using none
for reauthentication prompt just keeps juggling the user between auth0 and localhost.