Verify user phone numbers in Ruby on Rails with the Authy Phone Verification API
Tags: twilio, authy, ruby, rails
Published: 2017-09-05 11:01:26

---
title: Verify user phone numbers in Ruby on Rails with the Authy Phone Verification API
published: true
description: If you ever need to contact your application’s users by phone then it’s good practice to verify that the phone number they enter is in fact theirs. Let’s see how to verify phone numbers in a Rails 5 application using the Authy Phone Verification API.
tags: twilio, authy, ruby, rails
canonical_url: https://www.twilio.com//blog/2017/08/verify-user-phone-numbers-in-ruby-on-rails-with-the-authy-verification-api.html
cover_image: https://thepracticaldev.s3.amazonaws.com/i/44gdfwvodlmmpss7f2hs.jpg
---

If you ever need to contact your application's users by phone then it's good practice to verify that the phone number they enter is in fact theirs. Let's see how to verify phone numbers in a Rails 5 application using the <a href="https://www.twilio.com/docs/api/authy/authy-phone-verification-api">Authy Phone Verification AP</a><a href="https://www.twilio.com/docs/api/authy/authy-phone-verification-api">I</a>.

## What you'll need

To code along with this post, you'll need:

* <a href="https://www.twilio.com/try-twilio">A Twilio account</a>
* <a href="https://www.twilio.com/console/authy/applications">An Authy App which you can create in the Twilio console</a>, you'll need the API key
* Ruby and Rails installed, I am using the latest Rails 5.1.2 and Ruby 2.4.1

## Getting started

Create a new Rails application for this project:

```bash
rails new phone_verification
cd phone_verification
```

We need to add a couple of gems that we'll use in the project, open up the `Gemfile` and add `authy` and `envyable`. Authy is going to be used for the phone verification, envyable to <a href="https://www.twilio.com/blog/2015/02/managing-development-environment-variables-across-multiple-ruby-applications.html">manage environment variables</a>.

```ruby
gem 'envyable'
gem 'authy'
```

Install the gems, then initialise envyable from the command line:

```bash
bundle install
bundle exec envyable install
```

Open up `config/env.yml` and add your Authy app API key:

```yaml
AUTHY_API_KEY: YOUR_API_KEY_HERE
```

Now, initialise Authy itself by creating the file `config/initializers/authy.rb` and add the following code:

```ruby
Authy.api_key = ENV['AUTHY_API_KEY']
Authy.api_uri = 'https://api.authy.com/'
```

That is all the initialisation we need, we can now get on with building the application.

## Building the app

The process of verification is quite straightforward. 

* The user enters three bits of information
  * Phone number
  * Country code
  * Whether they want to verify by voice or SMS
* Our application makes a request to the API to initiate the verification
* The user receives a call or text message with a 4 digit code
* They then enter that code into a form in the application
* The code is sent off to the API, with their phone number and country code again, to verify
* If it is correct then the user has verified their number

We're going to need a controller that will both present the views we need as well as do the work to initialise the verification and actually verify the phone number. Generate a controller with:

```bash
bundle exec rails generate controller phone_verifications new create challenge verify success
```

This will create five actions and five views. We don't need the create and verify views, so you can delete those. It will also generate some routes. Open `config/routes.rb` remove the 5 new routes and replace them with:

```ruby
  resources :phone_verifications, :only => [:new, :create] do |p|
    collection do
      get 'challenge'
      post 'verify'
      get 'success'
    end
  end
```

This creates 5 routes which you can check out by running `rails routes` on the command line. They look like this:

```bash
bundle exec rails routes
                       Prefix Verb URI Pattern                              Controller#Action
challenge_phone_verifications GET  /phone_verifications/challenge(.:format) phone_verifications#challenge
   verify_phone_verifications POST /phone_verifications/verify(.:format)    phone_verifications#verify
  success_phone_verifications GET  /phone_verifications/success(.:format)   phone_verifications#success
          phone_verifications POST /phone_verifications(.:format)           phone_verifications#create
       new_phone_verification GET  /phone_verifications/new(.:format)       phone_verifications#new
```

## The first view

The `new` action needs to display a form to the user that takes their phone number, the country code of the country they are in and whether they want the verification by SMS or voice call.

To generate the list of country codes and make an interface that we can use to search by country, include the <a href="https://github.com/authy/authy-form-helpers">Authy JavaScript form helpers</a>. Add to the `<head>` of `app/views/layouts/application.html.erb`

```erb
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= stylesheet_link_tag    'https://cdnjs.cloudflare.com/ajax/libs/authy-form-helpers/2.3/form.authy.min.css', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/authy-form-helpers/2.3/form.authy.min.js', 'data-turbolinks-track': 'reload' %>
```

Now, in `app/views/phone_verifications/new.html.erb` replace the code that was generated with the following:

```erb
<h1>Verify your phone number</h1>

<%= form_tag(phone_verifications_path, method: :post) do -%>
  <% if @response %>
    <% @response.errors.each do |key, message| %>
      <p><%= message %></p>
    <% end %>
  <% end %>
  <div>
    <%= label_tag "authy-countries", "Country code:" %>
    <%= select_tag "authy-countries", nil, name: 'country_code', 'data-show-as': 'number' %>
  </div>
  <div>
    <%= label_tag "phone_number", "Phone number:" %>
    <%= telephone_field_tag "phone_number", nil, name: 'phone_number' %>
  </div>
  <div>
    <p>Verification method</p>
    <%= label_tag "method_sms", "SMS: " %>
    <%= radio_button_tag "method", "sms" %>
    <%= label_tag "method_call", "Call: " %>
    <%= radio_button_tag "method", "call" %>
  </div>
  <%= button_tag "Verify" %>
<% end -%>
```

This code sets up the form to submit the three fields. Using the ID `"authy-countries"` means that the `select_tag` will be picked up by the Authy JavaScript and augmented to become a searchable list of countries.

We also use `telephone_field_tag` to create an HTML input with a type of `"tel"` so that mobile devices show an optimised keyboard for entering telephone numbers.

Start up the server:


```bash
bundle exec rails server
```

Navigate to <a href="http://localhost:3000/phone_verifications/new">http://localhost:3000/phone_verifications/new</a> to see the new form and try out the country code field.

<img src="https://twilioinc.wpengine.com/wp-content/uploads/2017/08/numberpicker.gif" alt="When you start typing in the field, flags, numbers and country names show up. When you select one, the country code is left in the input box." width="600" height="400" class="aligncenter size-full wp-image-21385" />

## The verification process

Now we have our form to start the process, we need to begin the verification. Using the parameters entered into the form, we will build an API request to the Authy phone verification API and send it off. If it is successful we will present the form asking for the verification code, otherwise we should re-render the initial form and show the error.

In `app/controllers/phone_verifications_controller.rb` replace the empty `create` method with this code:

```ruby
  def create
    session[:phone_number] = params[:phone_number]
    session[:country_code] = params[:country_code]
    @response = Authy::PhoneVerification.start(
      via: params[:method],
      country_code: params[:country_code],
      phone_number: params[:phone_number]
    )
    if @response.ok?
      redirect_to challenge_phone_verifications_path
    else
      render :new
    end
  end
```

The key part here is the call to `Authy::PhoneVerification.start`. We pass the parameters we gathered from the user, including the way to contact them, the phone number and the country code. If the response to this is ok, then the verification process will start, otherwise there is an issue.

We already built in the code to display errors if something does go wrong. These lines in the view handle that:

```erb
  <% if @response %>
    <% @response.errors.each do |key, message| %>
      <p><%= message %></p>
    <% end %>
  <% end %>
```

Note too, that we save the phone number and country code to the session so that we can use them later. In a full application these would be saved against a user or phone number record in the database and we'd keep the ID of the record in the session.

## The challenge

We now need users to enter the 4 digits that the verification process sends them. Add the following code to `app/views/phone_verifications/challenge.html.erb`:

```erb
<h1>Challenge</h1>

<%= form_tag(verify_phone_verifications_path, method: :post) do -%>
  <% if @response %>
    <% @response.errors.each do |key, message| %>
      <p><%= message %></p>
    <% end %>
  <% end %>
  <div>
    <%= label_tag "code", "Enter the code you were sent:" %>
    <%= text_field_tag "code" %>
  </div>
  <%= button_tag "Verify" %>
<% end -%>
```

## Time to verify

Now we have the user's 4 digit code we need to verify it with the API. Replace the empty `verify` action in the `PhoneVerificationsController` with:

```ruby
  def verify
    @response = Authy::PhoneVerification.check(
      verification_code: params[:code],
      country_code: session[:country_code],
      phone_number: session[:phone_number]
    )
    if @response.ok?
      session[:phone_number] = nil
      session[:country_code] = nil
      redirect_to success_phone_verifications_path
    else
      render :challenge
    end
  end
```

This time the key part here is making the request to `Authy::PhoneVerification.check` passing in the phone number and country code that we saved earlier along with the code the user entered. If the response is ok this time, then the verification was a success and we can clear the session and redirect to the success path. In a real application you would likely mark that the user or phone record was indeed verified and save that in the database too.

If the code was wrong, we'll just show the challenge view again so that the user can try again if they made a mistake.

To finish off, add a success message to `app/views/phone_verifications/success.html.erb`:

```html
<h1>Congratulations!</h1>
<p>You have successfully verified your phone number.</p>
```

## Let's test it out

If you didn't start the server earlier, do so now:


```bash
bundle exec rails server
```

Go to <a href="http://localhost:3000/phone_verifications/new">http://localhost:3000/phone_verifications/new</a> and enter the correct details. When you get the phone call or SMS message, enter the verification code into the second form and you will see a message of success that your phone is verified.

<img src="https://twilioinc.wpengine.com/wp-content/uploads/2017/08/complete5.gif" alt="The whole process from start to finish: the user enters their phone number, country code and checks SMS, then they are directed to the challenge page where they enter a 4 digit code which is correct so directs them to the congratulations page." width="600" height="400" class="aligncenter size-full wp-image-21386" />

## Phone numbers? Verified!

That's how to get started with the Authy Phone Verification API in Rails 5. You can check out <a href="https://github.com/philnash/rails-phone-number-verification">the full code for this article on GitHub</a>. This application is far from complete of course, there is much more to do. You'd want to:

* save the phone number and its verification status to a user model in your database
* handle errors better, giving users the chance to resend or call again or check and update the phone number

If you've got any questions or comments, then please do get in touch. Leave me a comment below or give me a shout on <a href="https://twitter.com/philnash">Twitter</a>.


___

_[Verify user phone numbers in Ruby on Rails with the Authy Phone Verification API](https://www.twilio.com//blog/2017/08/verify-user-phone-numbers-in-ruby-on-rails-with-the-authy-verification-api.html) was originally published on the [Twilio blog](https://www.twilio.com/blog) on August 30, 2017._