Issue getting auth-0 set up with react project

Hey Auth0 community!

I have an enterprise react project I am migrating over to auth0 for user authentication, and I am having trouble getting users properly authenticated.

I have configured an auth0 application to be the staging environment for this project, meaning it’s Allowed Callback URL, Allowed Logout URL, and Allowed Web Origin lists all contain the proper urls (in this case, I have been running the project to be migrated on https://localhost:3000 and the demo app on https://localhost:3001). I have also migrated all of my staging users into auth0 and this application has access to them.

I have followed the react quickstart guide using my ‘staging’ auth0 application’s domain and client ID, as a demo app, and it works perfectly. I am redirected to our universal login page, and then back to the demo after successfully logging in. In the demo, I can see that the proper cookies have been set.

However, I have set up our react app to use the same domain and client ID, and when logging into our react application with the loginWithRedirect() method provided by auth0-react, the user is redirected to universal login, then back to our react application after login success (I can see the successful login on my user in the auth0 dashboard), but no cookies are set on the client. Essentially, our react app cannot tell that a user has just been authenticated - ‘isAuthenticated’ is always false and ‘user’ is undefined after login.

the code for our react project looks like this:

code for login page:

import React, { useEffect } from 'react';
import { useAuth0 } from "@auth0/auth0-react";
import { LoginWrap, LoginMat } from './styled';

const Login = (props) =>{

	const auth0 = useAuth0();

	useEffect(() => console.log(auth0), [auth0])

    return (
        <LoginWrap>
        	<LoginMat>
               	<h2>Log In</h2>
				<button onClick={() => auth0.loginWithRedirect()}>LOG IN</button>
    	</LoginMat>
	</LoginWrap>
    )
}

export default Login;

code for App.js

import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';

import { UserProvider } from 'context/User';
import { LiveProvider } from 'context/Live';
import { Auth0Provider } from '@auth0/auth0-react';
import AppRoute from 'containers/AppRoute';
import Layout from 'hoc/Layout';

function App() {
	
	return (
		<UserProvider>
			<Auth0Provider
				domain={process.env.REACT_APP_AUTH0_DOMAIN}
				clientId={process.env.REACT_APP_AUTH0_CLIENT_ID}
				redirectUri={window.location.origin} >
				<LiveProvider>
					<Router>
						<Layout>
							<AppRoute />
						</Layout>
					</Router>
				</LiveProvider>
			</Auth0Provider>
    	</UserProvider>
	);

}

export default App:

code for Router:

import React, { useContext, useEffect, useState } from 'react';
import { BrowserRouter as Switch, Route, Redirect, useHistory} from 'react-router-dom';
import { useAuth0 } from '@auth0/auth0-react';

import Home from 'containers/Home';
import UserContext from 'context/User';
import Login from 'containers/Login';

const AppRoute = () => {
	const { user } = useContext(UserContext);
	// already have a user so pulling out isAuthenticated and user from useAuth0 in this scope isnt possible (at least for now)
	const auth0 = useAuth0();

	return (
		<Switch>
			<Route exact path="/">
				{auth0.isAuthenticated && <Home />}
				{!auth0.isAuthenticated && <Redirect to={'/login'}/>}
			</Route>
			<Route exact path="/login">
				{auth0.isAuthenticated && <Redirect to={'/'}/>}
				{!auth0.isAuthenticated && <Login />}
			</Route>
		</Switch>
	);
};

export default AppRoute;

The idea is to be routed to the home page after isAuthenticated is true.

Instead, since no cookie is set after being redirected back from Universal Login, auth0.isAuthenticated is always false, and both auth0.user and auth0.error are undefined, we are just redirected back to login.

We need a way to get our react app to save the cookie correctly, so this cascade of failure does not happen.

Any help with this would be much appreciated. Thanks for your time!

Hi @zaronologylou,

I read this code and found it curious that you were doing import { BrowserRouter as Switch } so I created a project to try it out.

I was able to replicate the issue, but right off the bat, I noticed the usage of {!auth0.isAuthenticated && <Redirect to={'/login'}/>} is problematic.

The problem with that is we’re not giving the Auth0 enough time to check and renew the session.
I commented out the redirect so I could login, then I added this useEffect to confirm that after some seconds isAuthenticated does become true:

useEffect(() => {
  if(auth0){
    console.log("Authenticated?:", auth0.isAuthenticated);
  }
},[auth0]);

I recommend you to change this

{!auth0.isAuthenticated && <Redirect to={'/login'}/>}

to this. Leveraging isLoading so we redirect only after we’re 100% there’s no session present:

{auth0.isLoading && <div>Loading...</div>}
{!auth0.isLoading && !auth0.isAuthenticated && <Redirect to="/login" />}

I also suggest you try this guide out because it feels like you’re manually implementing withAuthenticationRequired.

Hope that helps!

2 Likes

Hello @jcespinoza! I really appreciate you getting back to me.

I implemented what you said, and it worked! As we migrate the app we will have to revisit how we are protecting routes as well, as per your suggestion (and the article linked).

Thank you so much for all of your help!

Teamwork makes the dreamwork!

1 Like