How to Leverage Amazon Amplify for Enhanced Authentication in React Apps

Tech Community • 6 min read

In the world of web development, having robust authentication and user authorisation processes is critical. And having a user-friendly and secure solution like Amazon Amplify to manage user access and identities provides a well-rounded solution to the authentication process of a React application. 

This post is an introduction on how to configure Amazon Amplify for a React Application and the uses of best practices to handle authentication and authorisation for users.

What is Amazon Amplify?

Amazon Amplify is a set of tools and services from Amazon Web Services (AWS) that enables developers to build scalable full-stack applications. It provides an easier way to integrate AWS backend services into your web and mobile applications.

Why Choose Amazon Amplify for Your React Application?

Seamless Integration with React

Amazon Amplify integrates smoothly with React applications. It provides a comprehensive JavaScript library that works well with modern JavaScript frameworks, simplifying the integration of AWS services into your React app.

Secure and Easy to Use

Amplify handles user authentication securely, providing features like multi-factor authentication and encryption of user data. The easy-to-use API and pre-built UI components make it simpler to implement secure authentication flows.

Developer-Friendly Experience

Amplify offers a developer-friendly approach, from setting up the backend to deploying your application. Its CLI and GUI tools are designed to speed up development and deployment processes.

Setting Up Amazon Amplify in a React Application

Before integrating Amazon Amplify into your React application, you need to configure it to work with AWS services.

Initialising Amplify

  1. Install Amplify CLI: Use npm or yarn to install the AWS Amplify CLI.
  2. Configure Amplify: Run amplify configure to set up the Amplify project and connect it to your AWS account.
  3. Initialise Amplify in Your Project: Use amplify init within your React project to initialise Amplify.

Adding Authentication

  1. Add Authentication: Run amplify add auth to add authentication to your project. This sets up AWS Cognito in the backend.
  2. Deploy the Backend: Deploy your configuration using amplify push.

Integrating Authentication with React Using Amplify

Installing Amplify Libraries

Install the necessary Amplify libraries in your React project:

npm install aws-amplify

Configuring Amplify in Your React App

When you initialise AWS Amplify in your React project, it creates a configuration file (aws-exports.js) that contains all the necessary settings. This file is automatically generated when you run amplify push after configuring your services (like authentication) using the Amplify CLI.

Key Elements in aws-exports.js:

  • Authentication: Contains your AWS Cognito User Pool ID, Web Client ID, and other authentication-related configurations.
  • APIs and Other Services: Information about configured APIs (GraphQL or REST), storage services, and more.

Import Amplify into your app and configure it with the generated AWS configurations in your root index file.

import Amplify from 'aws-amplify';
import awsExports from './aws-exports';

Amplify.configure(awsExports);

Creating Custom Authentication Components

While Amplify's pre-built UI components are convenient, creating custom components allows for greater flexibility and customisation to match your application's UI/UX design.

Custom Sign-Up Component

State Management: Use React's state hooks to manage form inputs like username, email, and password.

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

Form Submission: Handle the form submission using Amplify's Auth class.

import { Auth } from 'aws-amplify';

const signUp = async () => {
  try {
    await Auth.signUp({
      username: email,
      password,
      attributes: {
        email, // optional
      },
    });
    console.log('Sign up successful!');
  } catch (error) {
    console.error('Error signing up:', error);
  }
};

User Interface: Build a form in JSX, binding your state variables to form inputs and setting up an onSubmit handler.

<form onSubmit={signUp}>
  <input
    type="email"
    value={email}
    onChange={(e) => setEmail(e.target.value)}
  />
  <input
    type="password"
    value={password}
    onChange={(e) => setPassword(e.target.value)}
  />
  <button type="submit">Sign Up</button>
</form>

Custom Sign-In Component

Similarly, for the sign-in component:

Form State: Manage the username and password inputs with state hooks.

Sign-In Logic: Use Auth.signIn() for signing in the user.

const signIn = async () => {
  try {
    const user = await Auth.signIn(username, password);
    console.log('Sign in successful!', user);
  } catch (error) {
    console.error('Error signing in:', error);
  }
};

Sign-In Form: Create a JSX form with input fields for username and password and an onSubmit handler.

Building Hooks for Private Routes

Using React hooks, you can create a mechanism to protect private routes in your application, ensuring that only authenticated users can access certain areas.

useAuth Hook

Create a custom hook, useAuth, to manage and provide authentication status throughout your application.

import { useState, useEffect, useContext, createContext } from 'react';
import { Auth } from 'aws-amplify';

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    checkUser();
  }, []);

  const checkUser = async () => {
    try {
      const userData = await Auth.currentAuthenticatedUser();
      setUser(userData);
    } catch (error) {
      setUser(null);
    }
  };

  return (
    <AuthContext.Provider value={{ user }}>
      {children}
    </AuthContext.Provider>
  );
};
export const useAuth = () => useContext(AuthContext);

Understanding bypassCache: true

In some cases you may want to use:

const userData = await Auth.currentAuthenticatedUser({ bypassCache: true
});

Default Behavior: By default, Auth.currentAuthenticatedUser() checks the user's current authenticated session from a local cache. This means it returns the session information stored in the local storage of the browser without making a network request to AWS Cognito.

With bypassCache: true: When you use Auth.currentAuthenticatedUser({ bypassCache: true }), it bypasses the local cache and forces a network request to AWS Cognito to retrieve the latest session information.

Scenarios for Using bypassCache: true

Session Validity Check

If you want to ensure that the session information is up-to-date with what's stored on the server, bypassing the cache can be useful. This is particularly relevant in scenarios where session changes might have occurred through other means or in different sessions.

Multi-Tab/Multi-Window Environment

In applications where a user might be logged in across multiple tabs or windows, using bypassCache: true ensures that the session status is consistent across all instances.

Post-Authentication Actions

After certain critical actions like password changes, profile updates, or security settings modifications, you may want to revalidate the session to ensure that all changes are properly reflected and acknowledged by the server.

Protecting Routes

By wrapping your application with the AuthProvider you’ll have access to the useAuth hook in your route configuration to protect private routes.

import { Route, Navigate } from 'react-router-dom';
import { useAuth } from './AuthContext';

const PrivateRoute = ({ component, ...rest }) => {
  const { user } = useAuth();

  return (
    <Route
      {...rest}
      render={(props) =>
        user ? <Component {...props} /> : <Navigate to="/login" />
      }
    />
  );
};

Conclusion

In summary, Amazon Amplify stands out as a powerful and developer-friendly tool that seamlessly integrates with React to provide robust authentication and authorisation solutions. 

Through this guide, we've explored the streamlined process of setting up Amplify in a React project, highlighted the ease of integrating essential authentication functionalities, and demonstrated the flexibility offered by custom authentication components.

Amplify's ability to simplify complex authentication workflows, while offering a high degree of customisation and security, makes it an excellent choice for React developers aiming to enhance their applications' user experience and security.

For more detailed information and advanced features, be sure to check out Amazon Amplify Documentation. Happy coding!

Get in Touch.

Let’s discuss how we can help with your cloud journey. Our experts are standing by to talk about your migration, modernisation, development and skills challenges.

Ilja Summala
Ilja’s passion and tech knowledge help customers transform how they manage infrastructure and develop apps in cloud.
Ilja Summala LinkedIn
Group CTO