How to add Auth0 authentication to React apps

No matter what kind of software you’re creating, ensuring security is a top priority in today’s application landscape. As more users access the web, safeguarding their information and maintaining your application’s reliability has become vital aspects of building a trustworthy web app.

Constructing authentication is more than just challenging in terms of implementation; it’s also a big security concern. To establish a strong and secure authentication process in your application, turning to a specialized authentication service provider like Auth0 can be incredibly effective.

In this tutorial, we’ll explore how to seamlessly integrate authentication into a React application using Auth0.

React and Auth0

React has gained immense popularity as a tool for creating lively and interactive user interfaces. In contrast, Auth0 stands as a robust platform for authentication and authorization. It equips developers with the means to smoothly establish secure authentication mechanisms.

Now, let’s look at some of the well-known features Auth0 brings to the table.

Auth0 Features

      • User Authentication: Auth0 offers various authentication methods, including social logins (Google, Facebook, etc.), usernames and passwords, and more.

      • Security: Auth0 handles security concerns like hashing passwords and managing tokens independently, doing all the heavy lifting for you.

      • Customization: Auth0 provides ways to customize the authentication experience to match your application’s design. You can use their built-in templates to easily customize the UI of your authentication pages without coding. You can also get more fine-grained control over how your authentication page should look by writing your own CSS. Moreover, you can further customize the authentication flows as well.

    Finally, using Auth0 in React is incredibly simple. Let’s explore that now.

    Setting up the React app

    To start, make sure you have Node.js and npm (Node Package Manager) installed. You can create a new React application using the Create React App (CRA) tool.

    We’ll use the following command to create a new React app:

    
    npx create-react-app auth0-react-app
    cd auth0-react-app
    
    

    Let’s also install the auth0-react-sdk:

    
    npm install @auth0/auth0-react
    
    

    Setting up Auth0

    Let’s understand how we can set up Auth0 for your React application. We’ll do so using the following step

      1. Create an Auth0 Account
      1. Create a new Auth0 Application
      1. Get your application keys from the “Settings” tab
      1. Configure the callback URL to your local React application

    You can also follow this video step by step to set Auth0 for your React application:

    Integrating Auth0 into the React App

    Now that we’re all set to integrate Auth0 in our React app, first, we’ll wrap our React app inside the <Auth0Provider/> component in the src/index.js file:

    
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import { Auth0Provider } from '@auth0/auth0-react';
    import App from './App';
    const root = createRoot(document.getElementById('root'));
    root.render(
    <Auth0Provider
    domain={YOUR_AUTH0_DOMAIN}
    clientId={YOUR_AUTH0_CLIENT_ID}
    authorizationParams={{
    redirect_uri: window.location.origin
    }}
    >
    <App />
    </Auth0Provider>,
    );
    
    
    

    This will let us use the useAuth0 hook throughout our app to access authentication-related functions and states. Make sure you use your own Auth0 application’s domain and client Id against the domain and clientId prop in the provider.

    Login/Signup with Auth0

    Let’s create a simple LoginButton component that calls the loginWithRedirect method on our Auth0 app. This button, when clicked, will call Auth0 to load its authentication page, which will handle the authentication for us.

    
    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    const LoginButton = () => {
    const { loginWithRedirect } = useAuth0();
    return <button onClick={() => loginWithRedirect()}>Log In</button>;
    };
    export default LoginButton;
    
    
    

    Let’s render this component inside our App.js file:

    
    import './App.css';
    import LoginButton from './LoginButton';
    function App() {
    return (
    <div className="App">
    <LoginButton/>
    </div>
    );
    }
    export default App;
    
    

    Now if you click the Login button, you should land on the Auth0 authentication page where you can sign up or log in:

    Showing User Profile Information

    At the last step, if you simply go ahead and try to log in you’ll just be redirected back to the home page. We can actually get the logged-in user’s information using the useAuth0 hook. First, we’ll import this hook from the auth0-react SDK. Then, we’ll get the user object, isAuthenticated , and isLoading flags from the useAuth0 hook.

    Based on the value of isAuthenticated we can conditionally render the user’s profile information using the user object or the <LoginButton/> component:

    
    import './App.css';
    import LoginButton from './LoginButton';
    import LogoutButton from './LogoutButton';
    import { useAuth0 } from "@auth0/auth0-react";
    function App() {
    const { user, isAuthenticated, isLoading } = useAuth0();
    if (isLoading) {
    return <div>Loading ...</div>;
    }
    return (
    isAuthenticated ? (
    <div>
    <img src={user.picture} alt={user.name} />
    <h2>{user.name}</h2>
    <p>{user.email}</p>
    </div>
    ): <LoginButton/>
    );
    }
    export default App;
    
    
    

    If you now login again, you should see your profile information rendered on the page.

    Logging out

    Similar to log in, we can also create a simple <Logout/> button component that calls the logout method from the useAuth0 hook to logout the user:

    
    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    const LogoutButton = () => {
    const { logout } = useAuth0();
    return (
    <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>
    Log Out
    </button>
    );
    };
    export default LogoutButton;
    
    
    

    However, a small setting you’ll need to configure for this is to add http://localhost:3000 as the logout URL which Auth0 will redirect to after logout:

    We can then conditionally render the logout button:

    
    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    import LogoutButton from "./LogoutButton";
    import { useHistory } from "react-router-dom";
    const Profile = () => {
    const { user, isAuthenticated, isLoading } = useAuth0();
    const history = useHistory()
    if(!isAuthenticated) history.push('/')
    if (isLoading) {
    return <div>Loading ...</div>;
    }
    return (
    isAuthenticated && (
    <div>
    <img src={user.picture} alt={user.name} />
    <h2>{user.name}</h2>
    <p>{user.email}</p>
    <LogoutButton/>
    </div>
    )
    );
    };
    export default Profile;
    
    
    

    If you now click on the Logout button, you should no longer be logged in and your profile information will also disappear:


    Creating Protected Routes

    Currently, we only conditionally render the Login and Logout buttons along with the profile information. A regular web application will be much more complex than this and will have multiple routes that would render different pages and components.

    We can easily use the withAuthenticationRequired from the auth0-react SDK to create a protected route for our application. Protected routes ensure that only authenticated users can access certain parts of your application. To create a protected route, you can use a higher-order component (HOC) or a custom hook

    
    import { withAuthenticationRequired } from '@auth0/auth0-react';
    const ProtectedRoute = ({ component, ...args }) => (
    <Route component={withAuthenticationRequired(component)} {...args} />
    );
    
    
    

    Now you can simply use this ProtectedRoute HOC for all your protected routes:

    
    
    import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
    import './App.css';
    import LoginButton from './LoginButton';
    import Profile from './Profile';
    import ProtectedRoute from './ProtectedRoute';
    function App() {
    return (
    <div>
    <Router>
    <Switch>
    <ProtectedRoute path="/profile" component={Profile} />
    <Route path="/">
    <LoginButton/>
    </Route>
    </Switch>
    </Router>
    </div>
    );
    }
    export default App;
    
    
    

    The route /profile is a protected route and if a logged-out user tries to access it, Auth0 will automatically redirect them to the authentication page. Note that I’m using react-router-dom v5 in the above example. I have also abstracted the profile information UI in a separate <Profile/> component that I’m passing as the component prop inside the <ProtectedRoute/> component.

    Redirect to Profile Page after Login

    One last thing that we should do is automatically redirect users to the /profile page after they log in. We can configure this in our React app by listening to the isAuthenticated state from the useAuth0 hook. However, there’s a more simple way to do this. We can take advantage of the callback URL we set in our Auth0 application settings.

    First, we’ll need to update the redirect_uri in the Auth0Provider as shown:

    
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import { Auth0Provider } from '@auth0/auth0-react';
    import App from './App';
    const root = createRoot(document.getElementById('root'));
    root.render(
    <Auth0Provider
    domain="dev-3vdnutm4bamutlcn.us.auth0.com"
    clientId="6NcdcDp64csOeRMmPDqNqgwSNF7EuxQu"
    authorizationParams={{
    redirect_uri: "<http://localhost:3000/profile>"
    }}
    >
    <App />
    </Auth0Provider>,
    );
    
    
    

    Then, we’ll need to update the same in the callback URL on our application settings page:

    Now after login, you should be automatically redirected to the profile page.

    Testing the Authentication Process

    During development, it’s essential to test the authentication process thoroughly. One tool that can assist in this is Requestly. It allows you to modify API requests & responses and see how your app performs in various scenarios.

    Download the Requestly desktop app and connect your Chrome window where your React app is running. After this, you should be able to see all the network requests between your React app and Auth0’s servers on Requestly. We’ll test two simple scenarios by modifying the response body of Auth0’s requests using Requestly.

    When you log in, you’ll notice a request sent out to Auth0 to the endpoint https://dev-3vdnutm4bamutlcn.us.auth0.com/oauth/token . This request actually gets the necessary authentication token that is used to fetch your profile information on the Profile page.

    Let’s modify the response to this request by returning an empty authentication token. We’ll set the access_token field in the API’s response as empty:

    Now, let’s test the Login flow again:

    As you can see, Auth0 neither allows us to get redirected to our own Profile page, nor fetches or displays any profile information. This means that the access_token is essential for this flow, and its absence should break the flow for security purposes.

    Now, let’s delete the rule so we can log in securely. This time, we’ll modify the response to the logout request.

    I can simply search for a specific request I wish to find. In this case, I search for “logout” and return a 500, an erroneous status code in the request instead of the regular 302 it returns. Since this is a redirect request, we need to confirm two things. A status code 500 should now block the redirect but the logout should happen and we shouldn’t be able to access the profile page after that. Let’s test it now:

    As you can see, we see the response of the logout request on the page now but the redirect doesn’t happen because of the 500 status code we set. However, logout does happen successfully nevertheless and an attempt to go to the profile page lands us back to the login page.

    Conclusion

    Adding authentication to a React application using Auth0 is a powerful way to enhance security and provide a smooth user experience. With Auth0’s features and the seamless integration into a React app, you can confidently build applications that protect user data while providing a great user experience.

    This article was written by:

    Siddhant Varma

    Siddhant Varma

    Siddhant is a technology-agnostic engineer passionate about creating utility-rich and user-friendly software. I love sharing my learning about new tools, frameworks and technologies with the developer community.

    Share this article:

    You may also like