Introduction
This article will cover phone number-based authentication basics using React and Altogic, a backend-as-a-service platform using it’s client library. You can checkout the Github repository.
So, what is phone number-based authentication?
Users can sign up for the application by providing their phone number and password only. This authentication method does not require users to specify their email addresses. Thus, users can log in to the application using their phone number and the password they set when signing up.
With phone number authentication, the application will send an SMS code to the user through Twilio. After users receive the SMS message from the provider, they can use this code to verify their phone number.
It is also possible to set up the authentication system through other providers such as MessageBird and Vonage.
In the rest of the article, I’ll explain how phone authentication works and set up phone number authentication to a Web application using the Altogic Client Library and React as a frontend.
YouTube Promo Video
How does Phone Number Based Authentication work?
Authentication with the Phone Number consists of a few steps:
Users can enter their phone number and password on the Sign Up page.
Then the system will send an SMS to the given phone number with Twilio.
After the user enters the verification code in the SMS, the system completes the phone number verification.
-
Users will be able to sign in 2 ways:
- Sign in with credentials: Password and phone number
- Sign in with One-Time Passwords(OTP), where OTP is sent as an SMS message
OTP: The automatically generated password authenticates the user for a single session.
Developers can either configure the validity period of the verification code or the user session duration.
How to Setup Phone Number Based Authentication with Altogic?
Creating App in Altogic
To enable phone number authentication, we need to create an app in Altogic.
We can create an app with the Altogic Designer really fast. To create an app via the Designer:
Log in to Altogic with your credentials.
Select New app.
In the App name field, enter a name for the app.
And click Create.
Here, you can customize your subdomain, but not necessarily to do, Altogic automatically creates one for you, which will be your envUrl
. You don’t need to worry if you lost your envUrl
; you can get it from the Environments view of Designer.
After creating our app, we need envUrl
and clientKey
to access our app via Altogic Client Library to create a web application.
In order to get the clientKey
we need to enter the app which we have created before and;
Click on App Settings at the left-bottom of the designer.
And click on Client library keys section.
We can create new clientKey
from that page, but thanks to Altogic for creating one clientKey
automatically for us, so let’s copy the existing clientKey
from the list.
Really cool! Now everything is ready at the backend, time to continue Twilio Integration.
Twilio Integration
You need to sign up for Twilio with a free/paid trial. You need to get the Account SID and Auth Token for integration with Altogic Client Library.
If you will use the free trial, you will need to take Twilio phone number to send SMS messages to the users.
Create an Account in Twilio
Open Console
Click Get a trial phone number on the left-top of the Console
Copy Account SID, Auth Token and My Twilio phone number values to the clipboard
Now, we’ve copied the configuration credentials to the clipboard. In trial accounts, you have to specify the verified phone numbers, which we defined as “to number” in Altogic.
-
Click on the Explore Products in the left sidebar
- Be sure that **Messaging **and **Phone Numbers **products are selected.
Now you can navigate to the Verified Caller IDs page by Sidebar → Phone Numbers → Manage → Verified Caller IDs.
You should add your phone number as a Verified Caller from here.
And finally, you have to give geo permission to your phone numbers region. You can go to this page by Sidebar → Messaging → Settings → Geo permissions.
💡 After configuring the Twilio account, you have to enable the phone number and password based sign up from Designer → App Settings → Authentication → Mobile Phone Authentication → Enable phone number and password based sign up in Altogic client library.
Paste the Twilio Account SID,Twilio Authentication Token and Twilio Phone Number to the related fields.
Frontend Development
Installation
Before installing the application, be sure you have already installed NodeJS
in your development environment.
To install
💡 You can visit: https://nodejs.org/en/download/ to download.
To get started, open the terminal and create a new React project
// creates a react app with the name of `altogic-react-phone-authentication-tutorial`
npx create-react-app altogic-react-phone-authentication-tutorial
The above command creates a React project in the altogic-react-phone-authentication-tutorialdirectory
.
cd altogic-react-phone-authentication-tutorial
touch .env
Create a .env
file in the root directory of your application, open the file in your editor and paste the following.
Replace YOUR-APPLICATION-ENV-URL
and YOUR-APPLICATION-CLIENT-KEY
with the envUrl
and clientKey
you copied before, then return to your terminal.
Install the Altogic Client Library to our project by using NPM or Yarn by running the following command:
// Installation of Altogic Client Library with NPM
npm i altogic
Next, create a file to handle the Altogic services and client.
Go back to your root directory and follow the commands below:
cd src
mkdir helpers
cd helpers
touch altogic.js
altogic.js
will be created in the src/helpers
directory. Open the file in your editor and paste the following.
The third parameter of createClient function signInRedirect
handles the redirection to the Sign In page automatically when you have invalid session tokens or signed out. This is a beneficial feature for managing sessions in scenarios when you sign out from your mobile phone.
Building Main React Components
The next step is to create the components that we’ll need for our application,
SignIn
— A form component that allows the user to sign in.SignUp
— A form component that allows the user to sign up.Verification
— A form component that verifies phone number.Home
— A component that displays whether or not authentication was successful.RequiresAuth
A wrapper component that checks whether the user is authenticated before rendering a component; otherwise, it redirects the user to the signup/login page.RequiresNotAuth
— A wrapper component that checks whether the user is not authenticated before rendering a component; otherwise, it redirects the user back to the profile page(for example Sign In page).App
— The main application component. It renders all the views with their properties.Sessions
— A table component that allows user to manage and view their sessions.Profile
— A component that users can view and manage profile data.
switch to the root directory of your react application and run following commands:
cd src
mkdir pages
cd pages
touch SignIn.js SignUp.js Verification.js Home.js Sessions.js Profile.js
Going back to src directory again, and creating ‘components’ directory. We will create ‘Routes’ directory under ‘components’ directory:
cd ..
mkdir components
cd components
mkdir Routes
cd Routes
touch RequiresAuth.js RequiresNotAuth.js
This creates a pages directory with the components in the src
directory. Your folder structure should look similar to the screenshot
We’ll be using React Context API to manage the user and session data, and pass them to the components rendered based on whether the user is authenticated or not. We’ll also be using React Router to handle routing.
Go back to your root directory and open the terminal:
cd src
mkdir context
cd context
touch AuthenticationContext.js ModalContext.js CounterContext.js
To install React Router run the following command.
npm install react-router-dom
We will use Tailwind CSS and Headless UI library for styling the project. Run the following commands in the root directory to install the library.
npm install -D tailwindcss postcss autoprefixer
npm install @headlessui/react
Below command will create tailwind.config.js file:
npx tailwindcss init -p
Open the tailwind.config.js in editor and copy/paste following script to configure template paths:
Open index.css file in src directory and add the following directives:
And we will use Font Awesome Icons in our project. You should install the Font Awesome Library to have well-looking components.
- Add SVG Core:
npm i --save @fortawesome/fontawesome-svg-core
- Add Icon Packages:
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons
- Add React Component
npm i --save @fortawesome/react-fontawesome@latest
Since we built a phone number-based authentication app, we will need a phone number input field. We will use react-phone-number-input library to increase UX.
npm i react-phone-number-input
Finally all dependencies have been installed on our local machine. We can start our application by typing npm run start on the root directory. Let’s start coding!
Implementation
First of all, we will need some interface views and components such as;
Verification
Phone number verification pageResetPassword
andResetPasswordCode
Sends users an SMS to reset their passwordNotVerified
Informs users that their phone number is not verified yet, and resends verification codeCounter
Simple countdown timer for verification codes validityFooter
,Header
,ProfileDropdown
Navigation bar and footer badgeNotification
Informs users about the responsesSessionTable
andSessionItem
for listing sessionsChangeCredentials
Tab structure to change view forChangePhone
andChangePassword
PrimaryButton
andSecondaryButton
Custom buttons
Open your root directory and copy&paste lines one by one to create files.
cd src/components
touch Counter.js Footer.js Header.js Notification.js ProfileDropdown.js SessionItem.js SessionTable.js
mkdir Buttons
mkdir Profile
cd Buttons
touch PrimaryButton.js SecondaryButton.js
cd ../Profile
touch ChangeCredentials.js ChangePhone.js ChangePassword.js
We will need two parent components that instruct routing rules to their child component. Rules mean,
Authenticated users are not able to view Sign Up and Sign In pages.
Unauthenticated users are not able to view Profile and Sessions pages.
Since we have restricted rules, We have designed special particular components that restrict the child components: RequiresNotAuth and RequiresAuth
RequiresNotAuth.js
App.js This will be main component of our application. All routes and views will be rendered in App component.
As you can see in the App.js component, we have three different Provider&Context structure:
AuthenticationProvider: Stores functions, states that are related with authentication, such as calling Altogic Client Library functions
ModalProvider: Manages push notification flow in the app
CounterProvider: Stores and handles the deadline of the verification code’s expiry date
Just for now, I am skipping the implementation of AuthenticationContext, we will have further been discussing “How to build context provider structure and how it works?”.
Since we built a phone number based authentication app; we need SignIn
and SignUp
components to handle form actions. I’ve excluded all the functions ,which works asynchronously because of the Altogic connections, to the Authentication Context to manage and access it easily from other components.
Let’s start coding the SignUp
component first. We have a form structure to receive necessary data from the user. There is a button to handle the registration process at the bottom of the form structure. When you click this button, the signup()
function is triggered, defined in the 23rd line. Here, we call context.signup()
function defined in AuthenticationContext. Thus, Altogic functions stay together and stored in the context.
We’ve entirely coded the sign up form. Now, we need a sign in form to sign users in.
We’ve developed signin()
function -in line 24-, that will be triggered after the user clicks the button. Like with the SignUp
component, context.signin()
will be triggered inside the component’s own function.
We have finished the implementation of the Sign Up and Sign In page. Since the users have to verify their phone number, we need to built a Verification
component, which will take verification code as single parameter. When you click to the button, verify()
defined inside the function, will be executed. In this function, we execute context.verifyPhoneNumber()
function to verify our phone number with Altogic.
The common point of the three component SignIn
, SignUp
and Verification
is; they three have buttons, functions and forms inside the component. Also, they also importing AuthenticationContext
as context. I want to explain the simplified workflow of communications between components and contexts:
User clicks the button Sign In, Sign Up, Verify
Clicking triggers
signin()
,signup()
,verify()
function inside componentcontext.signIn()
function is called byhandleClick()
function
Authentication Context
Finally, we came to the Context API part. Before moving on to the coding section, I think going over the Altogic Client Library functions will be very helpful.
altogic.auth.signUpWithPhone(phoneNumber, password, name) → Takes 3 parameters (Name field is optional)
altogic.auth.signInWithPhone(phoneNumber, password) → Return user and session response if the credentials are correct
altogic.auth.signOut(token) → Kill the given token and sign out from the related session
altogic.auth.signOutAll() → Sign out from all session related with your account
altogic.auth.resendVerificationCode(phoneNumber) → Resend verification code to verify your phone number
altogic.auth.changePassword(newPassword, oldPassword) → Change password
altogic.auth.getAllSessions() → Get list of all active sessions with your account
altogic.auth.sendResetPwdCode(phoneNumber) → Send a verification code to your phone number if you forgot your password
altogic.auth.resetPwdWithCode(phoneNumber,code,password) → Reset your password
altogic.auth.changePhone(password, phoneNumber) → Change phone number function takes phone number and password as arguement
altogic.auth.verifyPhone(phoneNumber, code) → Verify phone number with your verification code that comes to your phone number
Here we came to the one of the core component and structure of app, AuthenticationContext
created using useContext()
hook. Context is used to generate shared data accessible across the component hierarchy without passing props to each component. For example, isAuth
state stores the boolean value of is user authenticated or not. Almost every component must use the isAuth
state to handle it’s internal functionalities. I could pass props to each component like parent to child. However it is not flexible and easy to use. I built an AuthenticationContext
to handle and manage all the data and functionalities related with authentication.
I defined all my Altogic functions and related states in AuthenticationContext
to distribute it to the child components.
BONUS: EXTRA FEATURES
You can find extra features in the shared repository. Also you can find more and more functions, database queries, etc. In fact all your needs to build a backend app.
Upload profile photo
Remove profile photo
Update credentials(phone number and password)
List all sessions
Sign out from other sessions
Sign out from all sessions
You can see the list of related Altogic functions with above features:
Conclusion
In this tutorial, we walked through how to secure and verify your users in a React app using Altogic, Twilio and Tailwind CSS. Phone number-based authentication is one of the standard authentication method in the sector. Additionally, as a full-stack developer, I have to say that building the backend of the phone number-based authentication apps becomes so confusing to handle with coding the backend and integrating the 3rd party SMS providers simultaneously. Altogic provides terrific services and functions to create a backend app for phone number authentication. As we experienced in the article, it took just a few lines of code to build a backend app.
This super powerful and easy-to-implement app should be a baseline for your phone number-based projects, and you would develop on it. You should check out the repository for the application we built on GitHub for further details.
Top comments (0)