2015-06-18

You’ve undoubtedly done something like this before:

That’s the SMS phone verification for AirBnB, which uses Twilio to allow hosts and guests to chat without sharing their actual phone numbers. In this tutorial, we’ll integrate SMS phone verification into a Rails 4 app using AJAX and Twilio.

Warning: There are a bunch of great reasons to grab a user’s phone number, but if your end goal is two-factor authentication, you should close this tutorial right now and use Authy instead. 2FA is a tricky beast, wrought with edge cases and security concerns — it’s typically a bad idea to roll your own.

However, if you’re looking to verify phone numbers in your Rails app for some other reason, by all means press on.

Create the Model

First we need a Rails project (we’ll use a fresh one for the purposes of this tutorial, but it shouldn’t be too hard to replicate these steps to integrate SMS verification into your preexisting Rails 4 app):

Add the Twilio gem to your

:

Install your gems:

Create a

model to store:

the phone number itself

a randomly generated PIN

A flag indicating if the number has been verified

Create the database and run the migration:

Now we have the M in MVC. Let’s do the C.

Create the Controller

As mentioned before, our verification process has three steps:

The user enters a new phone number

Our app creates the phone number row and sends the user a PIN to enter back into the form

Our app verifies that the PINs match for the given phone number.

Add this code to

to create a route for each step:

Create the

controller we just referenced in those routes:

Inside the controller (found at

), add a straightforward

action that creates a

that we’ll use in a

block in the view:

The beginnings of our C are in place. On to the V.

Create the View

From the user’s perspective, SMS verification involves three steps:

Enter a New Phone Number

Verify the PIN

Receive a success or failure message

To avoid jarring page loads, we’ll use AJAX to complete the process on a single page like we saw in AirBnB’s example.

But before we create the phone verification form, let’s address a slight problem: default Rails views are hideous. We can remedy that by simply including an externally hosted Bootstrap stylesheet.

In

, add this line above where the application stylesheet is included:

Then replace that files current

with this:

Now that our page won’t make our eyes bleed, we can create a new phone number view:

Add this code to that file to create a form for Step 1:

Make sure everything looks okay. Start your Rails server:

Visit

in a browser and check out your form. Should look something like this:



Before we wire up that “Send PIN” button, add this to the same file to compete the view:

This code creates a from with:

A hidden field to store the phone number (we will update this field using AJAX after the user completes Step 1).

A text field for entering the PIN

A submit button

It also adds a

where we’ll display a message after we attempt to verify the PIN. Refresh your page and make sure you can see the elements.



But wait! We don’t need to see Steps 2 and 3 yet!

Add this CSS to

(Rails auto-created that file for you) to make them disappear when the page loads. We’ll reveal them at the appropriate time with AJAX:

Refresh the page and ensure that you’re back to only seeing Step 1. With our finished view, we’ll head back to the controller and model to make it work.

Generate a PIN and send it via SMS

For Step 2, we need a

action in our controller that will do four things:

Create the phone number entered into the form (or find it if it already exists)

Generate a PIN

Send the PIN via SMS

Return JavaScript to reveal and prepare Step 2 of the view

Add this action to

inside

:

The astute reader will notice that we used two methods on

that don’t exist yet exist.

Add this method inside your

class in

to generate a four digit PIN:

This method, called by the controller when a phone number is created, generates a PIN and saves the record.

Before we can send this PIN via SMS, we need three things from Twilio:

Your account SID

Your auth Token

An SMS enabled phone number

Go to your Twilio account dashboard and find your account SID and auth token:

Also head over to your phone numbers list and find one you want to use for this app.

We’ll set these values as environment variables along with your Twilio phone number. Phil Nash wrote a great post on the multitude of ways to set environment variables in Ruby, but for the sake of this tutorial, we’ll do it in the simplest way possible. Kill your server, then punch this into the same terminal window:

Add two methods to our

class to send an SMS.

This method creates a Twilio REST client:

This method sends the PIN via SMS:

Last thing our

action does is to return JavaScript that will:

Add the phone number to our hidden field

Reveal Step 1 and hide Step 2

Move the focus onto the PIN input

Create a new file:

Add this to that file:

And that’s it for

! Restart your server, reload your page and give it a try!

Verify the PIN

The third and final step in our phone verification is the easiest: we check to see if the entered PIN matches the generated PIN. If so, we update the verified flag on the phone number record and update the page with a happy message. Otherwise, sad message.

Add this

action to the

:

You’ll again notice that

isn’t a thing yet. Add this to your

model:

Finally, let’s write our JavaScript to update the status message in the view. Create a new file:

In that file, paste in this code that will display the appropriate status message depending on if the phone number is successfully verified, then reveal the

.

That’s it!

Next Steps

This should get the ball rolling on verifying phone numbers in your Rails app, but it’s not a complete yet. You’ll want to code up some answers to a few questions:

What if the entered phone number is already verified?

What’s the UX if they get the PIN wrong? Should there be a resend PIN button?

What keeps someone from bruteforcing the PIN? Should the PIN expire after X tries or Y minutes?

If you have any questions or suggestions on this tutorial, or would like to show off what you’ve used phone verification for, hit me up at gb@twilio.com or @greggyb.

Happy Hacking!

SMS Phone Verification in Rails 4 using AJAX and Twilio

Show more