Over the past year or so, I have been working with many companies around the world as a consultant with React Native Training. By far the number one question was how to properly implement real world user authentication.

There are many reasons for this, but it really comes down to two major ones in my opinion:

Many developers & companies are coming into React Native from the web where routing and navigation differ substantially.

State management matters a lot when reasoning about authentication in a React Native Application, and many developers & companies coming into React Native are learning both state management as well as navigation at the same time that they are learning the framework.

Even for seasoned React Native developers, implementing authentication with React Native has not been easy or straight forward up until now.

In this post, I hope to greatly simplify what has been up until this point a somewhat complicated task using some state of the art tooling along with clear and concise instructions.

This is a two part series.

In Part 1, we will wire up full user sign up and sign in using a real service, Amazon Cognito with AWS Amplify, allowing users to sign in with username + Password with two factor phone authentication.

This will get you most of the way as far as authentication functionality, while part two will focus on Navigation and state flow.

Amplify supports many category scenarios such as Auth, Analytics, APIs and Storage as outlined in this Developer Guide, but we are really only worried about Auth for purposes of this post.

In Part 2, we will continue using this project and will add a real world navigation flow that I have used many times in production as well as some nice styling. This will include Redux + React-Navigation.

To see the code for the final version of what we will be building in part 1, check out this repo

Getting Started

The first thing we need to do to get started is create a new React Native app and install any dependencies we will be needing:

Next, we need to link the Cognito SDK, which is a dependency of aws-amplify:

react-native link amazon-cognito-identity-js

Now that the dependencies are installed and linked, we will need to create a src directory in the root of the project, src to hold the future project files:

mkdir src

Next we need to configure our AWS credentials.

We can either do this manually in the Cognito console, or we can automate this using the AWSMobile CLI. I recommend using the CLI unless you already know how Cognito works.

Automated Configuration

First, we need to install AWS Mobile CLI:

npm install -g awsmobile-cli

Next, we need to configure the CLI to use your correct credentials.

Run the following command:

awsmobile configure

This will configure the IAM role of the user you will be working with. This will be the accessKeyId, & secretAccessKey of the user, as well as the region you would like to use.

If you already have the AWS cli installed and credentials configured, the cli will automatically have populated this configuration into your AWS Mobile configuration, which you can always override with the same command (awsmobile configure).

To see how to create a new IAM user and configure the CLI, check out the following video.

Next, we need to create two class methods to handle the sign up process.

The user needs to sign up (with username, password, email, and phone number), then we need to authenticate the user using their phone number.

Once the user has successfully signed up, Cognito will send an sms to the user that we will need to send back to the API to confirm the user is authenticated.

We need to have a form input with some state that will keep up with the input code once we have it.

To handle all of this, we’ll have three methods: signIn, confirmUser, and onChangeText. We’ll create a state variable called authCode and keep up with it in the onChangeText method for input of the auth code:

onChangeText will keep up with the TextInput value that will take in the authentication code once we get it.

signUp calls the amplify Auth.signUp function, passing in some hardcoded values (for now). Later once we verify this is all working, we will change these hardcoded values to be dynamic from other text inputs. If this signs up the user correctly, the phone number provided should receive an sms with the confirmation code, which we’ll use in the next step. This returns a promise, which we handle by logging out the returned values or handling the error.

confirmUser will take the sms confirmation that we type into the TextInput, and call the Auth.confirmSignUp function, passing in the username as the first argument, and the authCode as the second argument. This also returns a promise which we handle.

Now that the functionality is set up, we need to wire up our UI to work with these methods.First, let’s go ahead and import Button and TextInput from 'react-native':

If you have a successful sign up and confirmation, you should be able to go into the console at https://console.aws.amazon.com/cognito/ , find the User Pool that was created (it should start with the name of your React Native project unless you configured this manually or changed it in some way), and view the user that was just created.

If you want to view this entire setup process end to end, check out one of the above videos.