React Quickstart can't parse token in handleRedirectCallback

I am right now trying to implement a simple login with the auth0-spa.js
I am using the quickstart project, but the login process keeps getting stuck after I logged in with the help of the auth0 login form.

I receive the callback, but the application can’t parse the token of the url and continues to show the loading screen:

In every browser there is a different error message:

Chrome:
Uncaught (in promise) TypeError: Cannot read property ‘split’ of undefined

Fireforx:
TypeError: t is undefined

In Safari:
Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating ‘t.split’)

It seems to be a problem within the if condition in my useEffect function inside the auth-wrapper:

useEffect(() => {
const initAuth0 = async () => {
  const auth0FromHook = await createAuth0Client(initOptions);
  setAuth0(auth0FromHook);

  if (window.location.search.includes("code=")) {
    const { appState } = await auth0FromHook.handleRedirectCallback();
    onRedirectCallback(appState);
  }
  ...
};
initAuth0();
// eslint-disable-next-line
}, []);

I have been stuck with this problem for 2 days now.
Any help would be greatly appreciated!

Hi @carolin,

Welcome to the Auth0 Community Forum!

Are you migrating from auth0.js? I was just working through a problem with another user who was experiencing the same error.

Can you take a look at that and see if is similar?

If not, can you post some more of your init code so we can see what is going on.

Thanks,
Dan

Hi @dan.woda,
Thanks for getting back to me!

I am not migrating from auth.js, but I did try an example that used auth.js and doesn’t use the spa library. And this one worked.
Afterwards, I had a look at the migration guide that you sent me, but I still couldn’t figure out the problem.

This was the code with the auth.js library, that worked:

export default class Auth {
  constructor() {
    this.auth0 = new auth0.WebAuth({
      domain: process.env.REACT_APP_AUTH0_DOMAIN,
      audience: `https://${process.env.REACT_APP_AUTH0_DOMAIN}/userinfo`,
      clientID: process.env.REACT_APP_AUTH0_CLIENT_ID,
      redirectUri: 'http://localhost:3000/?callback',
      responseType: 'id_token',
      scope: 'openid profile'
    });

    this.handleAuthentication = this.handleAuthentication.bind(this);
    this.signIn = this.signIn.bind(this);
  }

  signIn() {
    this.auth0.authorize();
  }

  getProfile() {
    return this.profile;
  }

  handleAuthentication() {
    return new Promise((resolve, reject) => {
      this.auth0.parseHash((err, authResult) => {
        if (err) return reject(err);
        if (!authResult || !authResult.idToken) {
          return reject(err);
        }

        this.idToken = authResult.idToken;
        this.profile = authResult.idTokenPayload;
        // set the time that the id token will expire at
        this.expiresAt = authResult.idTokenPayload.exp * 1000;
        resolve();
      });
    });
  }
}

But when trying to make it work with auth0-spa.js, the redirect callback doesn’t work:

export const Auth0Context = React.createContext();
export const useAuth0 = () => useContext(Auth0Context);
export const Auth0Provider = ({
    children,
    onRedirectCallback,
    ...initOptions
}) => {
const [isAuthenticated, setIsAuthenticated] = useState();
const [user, setUser] = useState();
const [auth0Client, setAuth0] = useState();
const [loading, setLoading] = useState(true);
const [popupOpen, setPopupOpen] = useState(false);

useEffect(() => {
  const initAuth0 = async () => {
    const auth0FromHook = await createAuth0Client(initOptions);
    setAuth0(auth0FromHook);

    if (window.location.search.includes("code=")) {
      const { appState } = await auth0FromHook.handleRedirectCallback();
      onRedirectCallback(appState);
    }

    const isAuthenticated = await auth0FromHook.isAuthenticated();

    setIsAuthenticated(isAuthenticated);

    if (isAuthenticated) {
      const user = await auth0FromHook.getUser();
      setUser(user);
    }

    setLoading(false);
  };
  initAuth0();
  // eslint-disable-next-line
}, []);

const loginWithPopup = async (params = {}) => {
  setPopupOpen(true);
  try {
    await auth0Client.loginWithPopup(params);
  } catch (error) {
    console.error(error);
  } finally {
    setPopupOpen(false);
  }
  const user = await auth0Client.getUser();
  setUser(user);
  setIsAuthenticated(true);
};

 const handleRedirectCallback = async () => {
  setLoading(true);
  await auth0Client.handleRedirectCallback();
  const user = await auth0Client.getUser();
  setLoading(false);
  setIsAuthenticated(true);
  setUser(user);
};
return (
  <Auth0Context.Provider
    value={{
      isAuthenticated,
      user,
      loading,
      popupOpen,
      loginWithPopup,
      handleRedirectCallback,
      getIdTokenClaims: (...p) => auth0Client.getIdTokenClaims(...p),
      loginWithRedirect: (...p) => auth0Client.loginWithRedirect(...p),
      getTokenSilently: (...p) => auth0Client.getTokenSilently(...p),
      getTokenWithPopup: (...p) => auth0Client.getTokenWithPopup(...p),
      logout: (...p) => auth0Client.logout(...p)
    }}
  >
    {children}
  </Auth0Context.Provider>
);

};

And here I wrap the Auth0 provider around my App:

const onRedirectCallback = appState => {
// Temporary Firefox workaround
window.location.hash = window.location.hash; // eslint-disable-line no-self-assign

window.history.replaceState(
  {},
  document.title,
  appState && appState.targetUrl
    ? appState.targetUrl
    : window.location.pathname
);
};
ReactDOM.render(
 <Auth0Provider
  domain={config.domain}
  client_id={config.clientId}
  redirect_uri={window.location.origin}
  onRedirectCallback={onRedirectCallback}
>
  <App />
</Auth0Provider>,
document.getElementById("root")
);

Am I maybe missing something, when initializing the client with createAuth0Client ?
When using the WebAuth not only pass in the clienID, redirectURI, and the domain,
but furthermore specify the responseType, the scope and the domain.

Thanks already,
Carolin

Everything looks configured correctly.

Can you double check that you have this app registered as a SPA in the auth0 dash? It looks like this occurs when it is configured as a regular web app.

Let me know.

Dan

edit: Check out this thread for an example.

Hey Dan,

I just checked again. And it is configured as a SPA.

I even just created a completely new Application
Downloaded the sample React App and there is again the same error:

Here are my application settings:

I really don’t understand.
Shouldn’t the sample project just work out of the box?

Thank you again for any reply
Carolin

I figured it out!

I had declared a custom “Rule” in the beginning and completely forgot about it. Once I deleted it everything worked fine.

Turns out my rule applied to all my authorization requests and prevented Auth0 from sending back the User object. Thats why I actually logged in correctly, but my React App expected a the users profile back. But because it never arrived it was stuck in the loading state.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.