Getting started with serverless using Amplify + React - Part 2: Authentication

This tutorial aims to give an introduction to creating serverless web applications in the cloud. There are several providers of serverless tools, we will work with AWS Amplify which allows grouping and managing the tools that the application will use from a single console and with a single CLI. We will create a React application that allows authentication through Cognito, create endpoints to Lambda functions, save data in Dynamo DB, and additionally we will configure a CI/CD pipeline.

Initialize the Amplify project and add authentication

With the previous steps in Part 1, we got nothing but a normal React application and some dependencies installed. To integrate amplify it’s necessary to initialize the amplify project, for that be sure to have the amplify CLI installed as described in the first step and run:

amplify init

Running this command will start the amplify project, usually amplify detects the scaffold of your application and suggests a setup, you can either accept this configuration or choose the step-by-step path where the Amplify CLI will start asking you questions about the project, add an amplify folder to your root, create the aws-exports.js file which is where amplify keeps track of all the integrated services and modify the .gitignore file to add the generated files to it.

This was the configuration applied for this tutorial:

And the files in our project now look like this:

Now that the amplify project is configured, you can start adding services to it. To see the available commands just run amplify. But for the moment adding authentication for the user and integrating it in the React app is the goal, let’s run:

amplify add auth

This starts auth configuration asking questions about how to set it up. This is the configuration used for this tutorial:

As you can see here the configuration includes the creation of user groups. This gives the possibility to configure different types of users and permissions.

Once this is done, deploy the new service added to amplify to your AWS account with:

amplify push

To open directly the amplify console in AWS you can run

amplify console

There you will be able to see the services added to your project

Or it can be done directly in the CLI with

amplify status

Authentication was added to amplify locally and the service was deployed to the AWS profile used. Now the React application needs to be modified so that the user can log in using Cognito.

For that, AWS includes a Connected Component called Authenticator. This provides everything you need for the authentication flow. This is how to set it up in the React application:

In the index.tsx include Amplify, initialize amplify with the aws-exports, and add Authenticator.

import React from "react";
import ReactDOM from "react-dom/client";

import { Amplify } from "aws-amplify";
import awsExports from "./aws-exports";
import { Authenticator, View } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";

Amplify.configure(awsExports);

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <Authenticator.Provider>
      <Authenticator>
        <View>
          <h1>MyApp</h1>
        </View>
      </Authenticator>
    </Authenticator.Provider>
  </React.StrictMode>
);

Now if you yarn start the dev server in local, you will see the following instead of “MyApp”:

As you can see, now the user can sign in, create an account and reset the password. And it’s not only UI, it is working with emails, SMS, or 2FA to confirm the user. You can even set up Federation authentication to log in the user with Facebook, Google, Amazon, or Apple. So if you think about it, it just takes a few minutes to have a secure and well-designed authentication to your React application.

Since the “MyApp” h1 tag is wrapped in the Authenticator component you will see it once you log in.

Now the user needs a way to log out, let’s make some tweaks to the React app to make it more coherent and provide a sign-out method.

AWS UIKit comes with a set of useful components that you can check in the library's documentation. And Authenticator comes also with a hook that makes development easier. If the app is wrapped in Authenticator.Provider, useAuthenticator is available to get the signOut method, user info, and other functionalities. Applying the UIKit and useAuthenticator the application will look like this:

import React from "react";
import ReactDOM from "react-dom/client";

import { Amplify } from "aws-amplify";
import awsExports from "./aws-exports";

import {
  Container,
  Header,
  SpaceBetween,
  Button,
  AppLayout,
} from "@awsui/components-react";

import { useAuthenticator } from "@aws-amplify/ui-react";
import { Authenticator, View } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";

Amplify.configure(awsExports);

function App() {
  const { signOut } = useAuthenticator((context) => [context.user]);

  return (
    <AppLayout
      content={
        <Container header={<Header variant="h2">T-shirts App</Header>}>
          <SpaceBetween direction="vertical" size="l">
            <h1>You are logged in!</h1>

            <Button onClick={signOut} variant="primary">
              Sign Out
            </Button>
          </SpaceBetween>
        </Container>
      }
    />
  );
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <Authenticator.Provider>
      <Authenticator>
        <App />
      </Authenticator>
    </Authenticator.Provider>
  </React.StrictMode>
);

Done, now you have a complete user authentication flow.

Demo source code:

Check the full source code of this part of the tutorial here: https://github.com/stackbuilders/blog-code/tree/main/amplify-react-tutorial/part-2-authentication

Next Steps:

Part 3 of this tutorial will be about how to add an API, configure permissions and use it in the React front end.

Written by


Nataly Rocha

Nataly Rocha