getAccessTokenSilently not working in @auth0/auth0-react even with custom domain verified

I am building an app with React and have used the @auth0/auth0-react React sdk from Auth0.
During the development, i want to fetch auth0 token using getAccessTokenSilently (Auth0ContextInterface | @auth0/auth0-react)

I have a custom domain verified that is being used so it shouldnt trust in a third party cookie

import React from 'react';
import { useHistory } from 'react-router-dom';
import { Auth0Provider } from '@auth0/auth0-react';
import { getConfig } from '../../config';

const config = getConfig();

const Auth0ProviderHOC = ({ children }) => {
  const history = useHistory();

  const onRedirectCallback = (appState) => {
    history.push(appState?.returnTo || window.location.pathname);
  };

  return (
    <Auth0Provider
      domain={config.domain} // my custom domain
      clientId={config.clientId}
      redirectUri={window.location.origin}
      onRedirectCallback={onRedirectCallback}
      cacheLocation="localstorage"
    >
      {children}
    </Auth0Provider>
  );
};

export default Auth0ProviderHOC;

then i call the function in another file that is being wrapped by Auth0ProviderHOC

useEffect(() => {
    (async () => {
      try {
        const accessToken = await getAccessTokenSilently({
          authorizationParams: {
            audience: appConfig.auth0.audience,
            scope: 'read:posts'
          },
          cacheMode: 'on',
          detailedResponse: true
        });

        console.log({
          accessToken
        });
        setToken(accessToken);
      } catch (error) {
        Sentry.captureException(error);
        errorToast({
          title: 'Error',
          message: 'There were some issues initializing your login. Please refresh and try again.'
        });
      }
    })();
  }, [getAccessTokenSilently]);

But nothing happens… i cant log access token for example
If i change getAccessTokenSilently for getAccessTokenWithPopup, it works fine

How can i fix this?

Hey there @rafael4 !

Do you see any requests being made when you call getAccessTokenSilently if you inspect via the network tab? Are you using refresh tokens?

I’m curious if you are able to reproduce this behavior in the sample app configured to your specific environment?

Hello @tyf

Actually i am not using refresh token… should i use anywhere?
It’s weird that it even pass through the request

As you can see, i am login a string, then access token and then token, but in the browser i cant see log of console.log({accessToken})

In network i see these requests

if i simply change getAccessTokenSilentyle with getAccessTokenWithPopup it works perfectly

Thanks for the additional information! That’s odd, I’m unfortunately not entirely sure what could be going on. When calling getAccessTokenWithPopup is the user required to interact?

Yes, you should absolutely look to using refresh tokens and refresh token rotation as this is now industry best practice.

Luckily, it’s pretty straightforward to set configure auth0-react to handle this for you. As far as the SDK goes, you basically just need to pass the useRefreshToken prop. Other than that, you will want to make sure the API you’ve registered in Auth0 has allow offline access toggled on - Additionally, in the SPA application you are using asclient_id be sure to toggle refresh token rotation on.

Hey @tyf
I made some changes in my component and the weird behavior persists

This is my Auth0Provider HOC now

const Auth0ProviderHOC = ({ children }) => {
  const history = useHistory();
  const redirectUri = `${window.location.origin}/universal-login-callback`;

  const onRedirectCallback = (appState) => {
    history.push(appState?.returnTo || window.location.pathname);
  };

  return (
    <Auth0Provider
      domain={config.domain}
      clientId={config.clientId}
      authorizationParams={{ redirect_uri: redirectUri }}
      cacheLocation="localstorage"
      onRedirectCallback={onRedirectCallback}
      useRefreshTokens={true}
    >
      {children}
    </Auth0Provider>
  );
};

and this is my component

function UniversalLoginCallback({ loggingInUser = false, loggingInUserError, universalLoginUser = () => {} }) {
  const { isAuthenticated, user, handleRedirectCallback, getAccessTokenSilently } = useAuth0();
  const { code } = parse(location?.search, { ignoreQueryPrefix: true });
  const [loading, setIsLoading] = useState(false);
  const dispatch = useDispatch();

  useEffect(() => {
    if (!loggingInUser && loggingInUserError) {
      setIsLoading(false);
    }
  }, [loggingInUser && loggingInUserError]);

  useEffect(() => {
    if (code) {
      const processCallback = async () => {
        setIsLoading(true);
        try {
          await handleRedirectCallback();
        } catch (error) {
          Sentry.captureException(error);
          errorToast({
            title: 'Error',
            message: 'There were some issues initializing your login. Please refresh and try again.'
          });
          historyRedirect.push('/universal-login');
        }
        setIsLoading(false);
      };

      processCallback();
    }
  }, [handleRedirectCallback, history]);

  useEffect(async () => {
    if (isAuthenticated && user) {
      console.log({
        isAuthenticated
      });

      try {
        const token = await getAccessTokenSilently({
          authorizationParams: {
            audience: appConfig.auth0.audience,
            scope: 'read:posts'
          }
        });
      } catch (error) {
        console.log({
          error
        });
      }

      // console.log({
      //   token
      // });
      dispatch(universalLoginUser({ user }));
    }
  }, [isAuthenticated, user]);

  if (!loading && loggingInUserError) {
    return <SingleSignOnError errorMessage={loggingInUserError?.message} />;
  }

  return <SingleSignOnLoading />;
}

After set a try catch, i am receiving the following error when fetching the token:

{error: Error: Missing Refresh Token (audience: 'https://api.trayt.health/v2', scope: 'openid profile email…}

Now i atthetd useRefreshTokenFallback to true

const Auth0ProviderHOC = ({ children }) => {
  const history = useHistory();
  const redirectUri = `${window.location.origin}/universal-login-callback`;

  const onRedirectCallback = (appState) => {
    history.push(appState?.returnTo || window.location.pathname);
  };

  return (
    <Auth0Provider
      domain={config.domain}
      clientId={config.clientId}
      authorizationParams={{
        redirect_uri: redirectUri,
        audience: config.audience,
        scope: 'openid profile email offline_access'
      }}
      cacheLocation="localstorage"
      onRedirectCallback={onRedirectCallback}
      useRefreshTokens={true}
      useRefreshTokensFallback={true}
    >
      {children}
    </Auth0Provider>
  );
};
useEffect(async () => {
    if (isAuthenticated && user) {
      console.log({
        isAuthenticated
      });

      try {
        const token = await getAccessTokenSilently({
          authorizationParams: {
            audience: appConfig.auth0.audience,
            scope: 'read:posts'
          }
        });
      } catch (error) {
        console.log({
          error
        });
      }
      dispatch(universalLoginUser({ user }));
    }
  }, [isAuthenticated, user]);

But now even if isAuthenticated is true, i am receiving an error in try catch of getAccessTokenSilentyle saying that login is required

image

PS: I’m using incognito browser