Friday, 8 March, 2019 UTC

Summary

One time passwords (OTP’s) provide an extra security layer for applications, and in this tutorial we will set up a system to provide one time passwords to users via voice calls powered by Twilio’s amazing programmable voice SDK and Laravel.

After you’re finished you will have developed an OTP system that can serve as an extra security layer for various actions in your application. The OTP could be used for authentication, purchase actions or whatever actions you consider worthy of an extra layer of authorisation in your application.

Requirements

For this tutorial, we’ll assume the following:

You are familiar with the terminal (command line)

You have Composer globally installed

You are familiar with PHP and Laravel and have PHP 7.3.2+ installed

You can create a Laravel project.

You either have MySQL locally installed, or are able to use docker and docker-compose (see the “Database Considerations” section below for more on this)

Create a Laravel Project

First off we will be creating a new Laravel project.

$ laravel new twilio-voice-otp

Once the Laravel application is created, enter into the project directory and let the fun begin.

$ cd twilio-voice-otp

Database Considerations

Our application is going to need a database to store the OTP’s and handle whatever persistent data needs we might have. However, setting up the database and connecting it to our Laravel app is outside the scope of this tutorial, Laravel’s documentation provides instructions on how to connect to a database from a Laravel application. Ensure that you have your local database setup and connected to the app before we go on. If you’re interested in using Docker, follow the next steps, otherwise skip to “Twilio Account Setup”.

NOTE:If you prefer using Docker, you can copy the Dockerfiles (app.docker and web.docker) and the docker-compose setup found in the accompanying repository for this tutorial. Note that you also have to copy the vhost.conf file into your project directory as its configuration for the nginx server spun up by the docker-compose stack.

To start up the docker-compose stack run the following command:

$ docker-compose up

This command sets up everything needed to run the application and exposes the app at Localhost:1000.

Twilio Account Setup

Now that you have your Laravel application created and have connected it to your local database, you need to set up a Twilio account so you can use the Twilio Programmable Voice SDK as needed. Follow through the following steps to setup your Twilio account and begin using the Programmable Voice SDK.

Create an account with Twilio

Verify your phone number as requested by Twilio. You need to link a Twilio verified phone number to your account so that you can use it in testing Twilio’s various product offerings, including receiving the phone calls made in this tutorial.

Set up a Twilio phone number that can handle Voice. This is a different phone number from the one we verified in step 2 above. Twilio phone numbers are set up to handle various tasks like making phone calls, sending SMS messages, etc., whereas the verified phone number was set up so it could receive phone calls and messages.

NOTE: Once you upgrade your Twilio account you can make calls and send messages to other phone numbers including the verified phone number.

To set up a Voice enabled Twilio phone number, go to your console, and click on the “Get a Trial Number” button.

If you followed the default prompts, you should now have a USA Twilio phone number capable of making voice calls to your verified account phone number. Next up we’ll take a look at Twilio’s programmable voice SDK and how we can use it in Laravel.

Account Credentials

Before we begin writing code, there are some environment variables we require from our Twilio account console to authorize programmatic use of Twilio’s services from our application:

Create the environment variables below in your .env file, and ensure to replace the placeholder values with your actual account values. We will use these later to authorize the Programmable Voice SDK to make phone calls from our application.

Now that we have our Laravel app and Twilio voice phone number setup, we need to link them up so our Laravel application is able to make phone calls using Twilio, enter Twilio’s Programmable Voice SDK.

Twilio Programmable Voice allows you to make and receive phone calls in your application, alongside some other cool features like creating conference calls and transcribing call recordings. For this tutorial we only need to make phone calls from our Laravel application. Twilio has an amazing PHP SDK which we will use to drastically simplify the process of making phone calls from our application.

To get started, we'll install the Twilio PHP helper library. From your terminal, run the following command in your project directory:

$ composer require twilio/sdk

Create The View That Requests an OTP

Next we will create a simple view page with a button which requests a one time password from the system. Create a blade file called create.blade.php in resources/views/otp and copy the following code snippet:

As you can see, we've updated [email protected] to display the create OTP page to the user, and the following methods were added to the OTPController:

1. **generateVoiceMessage**

Twilio requires that we provide a url where it can get the TwiML that describes the call to be made. This function generates the TwiML response which includes the OTP code.

2. **validateOTP**

This function handles a POST request to validate an OTP that a user provides and redirects to the user to an appropriate page providing feedback depending on whether the OTP validation was successful or not.

We also need to add a generateVoiceMessage() function to the OTP controller. This method takes in the $otpCode and generates the TwiML code that defines the call which the user will receive.

NOTE: TwiML (the Twilio Markup Language) is a set of instructions you can use to tell Twilio what to do when you receive or make a call, SMS, or fax.

Update Routes

Ensure that routes/web.php has the following routes which power our application.

After updating our routes, we need to remove CSRF protection from the **generateMessage** route so that an external party (Twilio) can POST to that endpoint. Update the $except property in app/Http/Middleware/VerifyCsrfToken.php to the following.

As seen above, we create an instance of the Twilio Rest Client when our service class is instantiated. This rest client instance uses the account SID and auth token we stored in our .env file to authorize the Twilio library to carry out actions on behalf of your Twilio account.

The makeOtpVoiceCall function does exactly what the name signifies. It makes a call to a provided phone number with a predefined message which will include the OTP code.The generateTwiMLForVoiceCall function generates the TwiML XML that describes the call which will be placed to the user.

NOTE: If you're using a Twilio trial account, you can only make outgoing calls to phone numbers you have verified with Twilio. Phone numbers can be verified with your Twilio Console’s Verified Caller IDs.

.

### Storing OTP’s and Making the Phone Call

Now that we have created the OTPService, and the TwilioService, update the store method in the app/Http/Controllers/OTPController.php to create an OTP and make a call to the user once an OTP is created:

Upon success of the call, redirect to an OTP validation page, passing in the call ID of the call made to the user providing the OTP.

Creating the OTP Validation View

After creating the OTP and making the call to the user in the previous step, we redirected to an OTP validation view. Let’s create this view page now. Create validate.blade.php in resources/views/otp, and paste the following code snippet into it:

This page displays a form that asks the user to validate an OTP, and posts our OTP validation route upon validation.

Expose our Application Online using Ngrok

Remember when we said Twilio needs to query a url for the TwiML that describes the call to be made?

Well we are about to test our application but there's just one problem, our application is deployed locally. This works for viewing pages and carrying out actions from our system, but Twilio also needs to access the generateMessage route we defined over the Internet.

There are a number of services which facilitate exposing your localhost to the Internet, but one that we use in this tutorial is ngrok. ngrok is a free tool that lets you put the web app running on your local machine on the Internet.

Follow the official ngrok documentation to download and setup ngrok on your system.

Next, expose your application to the Internet by running the following command (replace 1000 with whatever port your app is running on).

$ ngrok http 1000

After running the ngrok command, you get an ngrok URL which your local app is now accessible via the Internet. Replace the APP_URL in your .env file with the ngrok URL.

// This is just a random test ngrok url. Replace it with yours APP_URL=http://3d3215a.ngrok.com

Testing the Application

If you've been able to get this far in the tutorial congratulations, we are done with the coding and what remains is to enjoy your wonderful new OTP system.

Navigate to the OTP creation route i.e otp/create to see the OTP request page

You can now request for an OTP, get a call and validate the OTP. Congratulations.

Conclusion

Because this is a tutorial focusing on Twilio Voice and Laravel, some implementation and security considerations were intentionally overlooked to reduce the scope of the tutorial.Things like OTP invalidation after a certain duration, deactivation of the OTP upon validation, linking of OTP's to the user who created them e.t.c were not included, so if you're building a production-ready system, take care to implement these features.

There you have it, a way to protect important actions in your application with one time passwords that you provide to users via voice calls. Enjoy!