loginWithRedirect leads to infinite loop on Incognito & Safari

Hi everyone,

I am running into an issue where using loginWithRedirect leads to an infinite loop on Incognito & Safari.

I am running:

    "@auth0/auth0-react": "^1.11.0",
    "@auth0/auth0-spa-js": "^1.22.4",
    "react": "^18.2.0",

My index.js file looks like:

import React from "react";
import ReactDOM from "react-dom/client";
import "./styles/index.css";
import "bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.js";
import App from "./App";
import store from "./redux/store/Store";
import { Provider } from "react-redux";
import { Auth0Provider } from "@auth0/auth0-react";

const {
  REACT_APP_AUTH_0_AUDIENCE,
  REACT_APP_AUTH_0_CLIENT_ID,
  REACT_APP_AUTH_0_CONFIG,
} = process.env;

// I followed the auth0 quickstart guide for setting up the Auth0Provider
// https://auth0.com/docs/libraries/auth0-single-page-app-sdk#getting-started

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <Auth0Provider
      domain={REACT_APP_AUTH_0_CONFIG}
      clientId={REACT_APP_AUTH_0_CLIENT_ID}
      redirectUri={window.location.origin}
      audience={REACT_APP_AUTH_0_AUDIENCE}
      scope="read:current_user update:current_user_metadata"
      cacheLocation="localstorage"
      useRefreshTokens={true}
    >
      <App />
    </Auth0Provider>
  </Provider>
);

My App.js looks like:

import React from "react";
import { useDispatch } from "react-redux";
import { NavBar, Footer, Loader } from "./components";
import { Container, Button } from "react-bootstrap";
import { BrowserRouter } from "react-router-dom";
import { useAuth0 } from "@auth0/auth0-react";
import RoutingMap from "./routes";
import Api from "./api/Api";
import "./styles/App.css";

const { REACT_APP_AUTH_0_AUDIENCE } = process.env;

const App = () => {
  const dispatch = useDispatch();
  const {
    user,
    isAuthenticated,
    loginWithRedirect,
    getAccessTokenSilently,
    getAccessTokenWithPopup,
  } = useAuth0();
  const [loading, setLoading] = React.useState(true);

  const opts = {
    responseType: "token id_token",
    scope: "openid profile",
    audience: REACT_APP_AUTH_0_AUDIENCE,
    display: "page",
  };

  React.useEffect(() => {
    dispatch({
      type: "SET_USER_DATA",
      params: { isAuthenticated, data: user },
    });
  }, [isAuthenticated]);

  React.useEffect(() => {
    const getTokenAndTryAgain = async () => {
      const accessToken = await getAccessTokenWithPopup(opts);
      await Api.initRestClient(accessToken).then((response) => {
        setLoading(false);
      });
    };

    const getUserMetadata = async () => {
      // Retrieves the user's ACCESS TOKEN in order to initialize the REST client
      try {
        const accessToken = await getAccessTokenSilently(opts);
        await Api.initRestClient(accessToken).then((response) => {
          setLoading(false);
        });
      } catch (error) {
        if (error.error === "login_required") {
           loginWithRedirect();
        } else if (error.error === "consent_required") {
          getTokenAndTryAgain();
        }
      }
    };

    getUserMetadata();
  }, []);

  let content = null;
 if (loading) {
    content = <Loader wholeScreenLoading={true} />;
  } else {
    content = (
      <div className="app">
        <NavBar />
        <Container className="body">
          <RoutingMap isAuthorized={isAuthenticated} />
        </Container>
        <Footer />
      </div>
    );
  }

  return <BrowserRouter>{content}</BrowserRouter>;
};

export default App;

WHAT IS HAPPENING
When I attempt to log in on Chrome Incognito or Safari, I am directed to the login page as normal for loginWithRedirect. Once I log in, I immediately redirect over and over again. I am constantly hitting the login_required error in this way. This does not occur on regular Chrome (I.E., not Incognito).

Ideally, my users could get the same loginWithRedirect flow they would normally get in the standard Chrome browser, which does work for me.

getTokenAndTryAgain works, however the popup flow is not appealing to my users, and is actively confusing for some of them. Also, I have attempted putting display: 'page' into the opts object for getAccessTokenWithProps, however this provides no visual change to the popup, and seems to do nothing at all.

Any assistance would be greatly appreciated!

1 Like