Skip to Content

How do I add login authentication to react?

How do I add login authentication to react?

Adding login authentication is an essential step in securing a React application. It ensures that only authorized users can access protected routes and resources. React itself does not have a built-in solution for authentication, but it can be easily implemented using third-party libraries.

Requirements for adding authentication

Here are the main requirements when adding login authentication to a React app:

  • Install an authentication library – Popular options include Auth0, Okta, Firebase Auth, Amazon Cognito etc.
  • Set up routes – Use React Router to configure a public route for login pages and private routes for pages users can only access when logged in.
  • Implement a login page – Create a page with login form that posts credentials to the authentication library.
  • Add a callback component – This handles the response from the authentication server and stores the token if login succeeds.
  • Redirect on login status – Redirect to a private or public route based on whether the user is authenticated or not.
  • Add user to context – Store user object in context to pass down user information to components.
  • Protect private routes – Check authentication status before rendering protected routes.
  • Add navigation guards – Check auth status before allowing navigation to certain routes.
  • Pass down user object – Components can access auth state through context.
  • Implement logout – Remove user info from context/state and optionally redirect.

Step 1 – Install an Authentication Library

The first step is to install and configure an authentication library. This will handle the login/logout workflow and integrate with the authentication server. Some popular options include:

  • Auth0 – Easy to integrate JavaScript SDK with React. Offers free tier.
  • Okta – Provides React components and hooks for authentication. Free developer plan.
  • Firebase Auth – Simple API from Google. Integrates well with other Firebase services.
  • Amazon Cognito – Manages user access with JWT tokens. Scales to large applications.

For this example, we’ll use Auth0. First install the @auth0/auth0-react package:

npm install @auth0/auth0-react

Then wrap the App component in the Auth0Provider and pass your Auth0 domain and client ID:

// src/index.js

import React from "react";
import ReactDOM from "react-dom";
import { Auth0Provider } from "@auth0/auth0-react";

import App from "./App";

ReactDOM.render(
  <Auth0Provider
    domain={process.env.REACT_APP_AUTH0_DOMAIN}
    clientId={process.env.REACT_APP_AUTH0_CLIENT_ID}
  >
    <App />
  </Auth0Provider>,
  document.getElementById("root")
);

This provides the Auth0Context to our app which contains things like the user object, login/logout methods etc.

Step 2 – Set Up Routes with React Router

Next we’ll configure our React Router routes. The common pattern is to have a public route for login pages that don’t require authentication. And private routes that should only be accessible to logged in users.

First import the needed components from React Router:

// src/App.js

import { Routes, Route } from "react-router-dom";

Then set up the app routes inside the Auth0Provider:

function App() {
  return (
    <Auth0Provider> 
      <Routes>
        <Route path="/login" element={<LoginPage />} />
        
        <Route path="/" element={<PrivateRoute><HomePage /></PrivateRoute>} />
      </Routes>
    </Auth0Provider>
  );
}

The /login route uses a regular <Route> component and doesn’t require auth. But the / route renders a PrivateRoute component that will check for an authenticated user before allowing access.

Creating the Private Route Component

The PrivateRoute component checks if the user is authenticated and redirects to the login page if not. If authenticated it renders the protected route.

// src/PrivateRoute.js

import { useAuth0 } from "@auth0/auth0-react";
import { Navigate } from "react-router-dom";

function PrivateRoute({ children }) {
  const { isAuthenticated } = useAuth0();

  if (!isAuthenticated) {
    return <Navigate to="/login" />;
  }

  return children;
}

Now only authenticated users will be able to access the routes wrapped in the PrivateRoute component.

Step 3 – Implement the Login Page

With the routes configured, we can create a login page that allows users to authenticate.

Import the useAuth0 hook from Auth0 to access the login method:

// src/LoginPage.js

import { useAuth0 } from "@auth0/auth0-react";

Then call the loginWithRedirect method when the login button is clicked:

function LoginPage() {

  const { loginWithRedirect } = useAuth0();

  return (
    <div>
      <h1>Log In</h1>

      <button onClick={loginWithRedirect}>Log In</button>
    </div>
  );
}

This will redirect users to the Auth0 login page. On successful login, they will be redirected back to the callback URL we configure next.

Step 4 – Handle Authentication Callback

After the user authenticates, Auth0 will redirect back to a callback URL we specify with some authentication data in the URL. We need to handle this callback route to process the response from Auth0.

First specify the callback path when configuring Auth0:

// src/index.js

<Auth0Provider
  // ...
  callbackPath="/callback"
>

Then create a component to handle the callback:

// src/CallbackPage.js

import { useAuth0 } from "@auth0/auth0-react";
import { useNavigate } from "react-router-dom";

function CallbackPage() {

  const { handleRedirectCallback } = useAuth0();
  const navigate = useNavigate();

  useEffect(() => {
    handleRedirectCallback()
      .then(() => {
        // Login successful
        navigate("/");
      })
      .catch(error => {
        // Login failed
        navigate("/login");
      });
  });

  return <div>Loading...</div>;

}

The handleRedirectCallback method will process the auth data, store the user token and return a promise. Once resolved, we can redirect to our private route and the user will be authenticated.

Step 5 – User Context and Private Routes

Now that we are handling logins and storing the user token, the last steps are:

  • Provide user data to components via context
  • Check authenticated status before rendering private routes
  • Redirect to login if auth check fails

First let’s access the user value from Auth0Context in our components:

// src/HomePage.js

import { useAuth0 } from "@auth0/auth0-react";

function HomePage() {
  
  const { user } = useAuth0();

  return (
    <div>
      Welcome {user.name}!
    </div>
  );
}

Now the user’s name and other properties are available in components wrapped in the Auth0Provider.

Next we need to update our PrivateRoute to check if there is a user object and redirect to login if not:

// PrivateRoute.js

function PrivateRoute({ children }) {
  const { user } = useAuth0();

  if (!user) {
    return <Navigate to="/login" />; 
  }

  return children;
}

This will help prevent access to private pages without authentication.

Step 6 – Implement Logout

The last piece is logging the user out when they click a logout button. Similar to login, we can call a logout method from the Auth0 React SDK.

Import the logout method:

// src/HomePage.js

import { useAuth0 } from "@auth0/auth0-react";

const { logout } = useAuth0();

Then call it when clicking the logout button:

function HomePage() {

  return (
    <div>
      <button onClick={() => logout()}>
        Log Out
      </button>
    </div>
  );
}

Auth0 will clear the user session and remove tokens from storage. You can also optionally redirect back to login.

Conclusion

This covers the main steps required to add login authentication to a React application using Auth0. The key points are:

  • Install Auth0 React SDK
  • Configure Auth0Provider
  • Set up routes and private route component
  • Create login page that calls login method
  • Handle auth callback redirect
  • Check user auth status before rendering private routes
  • Provide user object via context
  • Implement logout to remove session

Auth0 makes the authentication process easy to add to React apps. There are also other libraries like Okta and Firebase Auth that offer similar functionality and integration.

With the authentication flow in place, you can move on to connecting your React app to an API and database to build out full-stack application features.