---
title: "Phone verification using SMS via Twilio"
description:
  "These days it is a common need to verify Phone using SMS. In this blog we
  will show you how to do that using Twilio."
canonical_url: "https://www.bigbinary.com/blog/phone-verification-using-twilio"
markdown_url: "https://www.bigbinary.com/blog/phone-verification-using-twilio.md"
---

# Phone verification using SMS via Twilio

These days it is a common need to verify Phone using SMS. In this blog we will
show you how to do that using Twilio.

- Author: Santosh Wadghule
- Published: January 12, 2015
- Categories: Rails

In this blog post, I'm going to show you how to do phone verification using SMS
via Twilio. We will be using [Twilio](https://github.com/twilio/twilio-ruby)
gem.

## Requirement

- When a user signs up , we want to send an SMS to that user with a random
  string to verify user's phone number.
- If that user replies back with that code, then verify user's phone number in
  the app. Once the phone number is verified, then we can use that phone number
  for future use.

## Step 1: Create required columns in users table

Let's create `phone_number`, `phone_verification_code` and `phone_verified`
columns in the users table.

```plaintext
 $ bin/rails generate migration AddPhoneAttributesToUsers phone_number:string phone_verification_code:string phone_verified:boolean
```

Then run the migration.

## Step 2: Add phone number field in registration form

Add `phone_number` field in the registration form.

```plaintext
  <%= f.text_field :phone_number %>
```

## Step 3: Send an SMS with verification code

When a user submits registration form, we need to send SMS if phone number is
present. To handle this, add following code in `User` model.

```ruby
class User < ActiveRecord::Base
  scope :unverified_phones,  -> { where(phone_verified: false) }

  before_save :set_phone_attributes, if: :phone_verification_needed?
  after_save :send_sms_for_phone_verification, if: :phone_verification_needed?

  def mark_phone_as_verified!
    update!(phone_verified: true, phone_verification_code: nil)
  end

  private

  def set_phone_attributes
    self.phone_verified = false
    self.phone_verification_code = generate_phone_verification_code

    # removes all white spaces, hyphens, and parenthesis
    self.phone_number.gsub!(/[\s\-\(\)]+/, '')
  end

  def send_sms_for_phone_verification
    PhoneVerificationService.new(user_id: id).process
  end

  def generate_phone_verification_code
    begin
     verification_code = SecureRandom.hex(3)
    end while self.class.exists?(phone_verification_code: verification_code)

    verification_code
  end

  def phone_verification_needed?
    phone_number.present? && phone_number_changed?
  end
end
```

We have added 2 major changes in the user model,

- `set_phone_attributes` method is set in `before_save` callback.
- `send_sms_for_phone_verification` method is set in `after_save` callback.

In `set_phone_attributes` method, we are setting up the phone attributes mainly
sanitizing phone number and generating unique phone verification code. In
`send_sms_for_phone_verification` method, we send SMS to the user. Creation of
SMS for the phone verification message is handled in `PhoneVerificationService`
class.

```ruby
class PhoneVerificationService
  attr_reader :user

  def initialize(options)
    @user = User.find(options[:user_id])
  end

  def process
    send_sms
  end

  private

  def from
    # Add your twilio phone number (programmable phone number)
    Settings.twilio_number_for_app
  end

  def to
    # +1 is a country code for USA
    "+1#{user.phone_number}"
  end

  def body
    "Please reply with this code '#{user.phone_verification_code}' to
    verify your phone number"
  end

  def twilio_client
    # Pass your twilio account SID and auth token
    @twilio ||= Twilio::REST::Client.new(Settings.twilio_account_sid,
                                         Settings.twilio_auth_token)
  end

  def send_sms
    Rails.logger.info "SMS: From: #{from} To: #{to} Body: \"#{body}\""

    twilio_client.account.messages.create(
      from: from,
      to: to,
      body: body
    )
  end
end
```

In `PhoneVerificationService` class, we have defined `user` as an attribute
reader and in `initialize` method, we have set the user object to it. Now if you
see `process` method, it does lots of stuff for us.

Lets go through each method.

- `from` - In this method, we set up the twilio phone number e.g. programmable
  number.
- `to` - In this method, we set the phone number to which we want to send an
  SMS.
- `body` - In this method, we build text message with verification code.
- `twilio_client` - It creates twilio client based on twilio account SID and
  auth token.
- `send_sms` - And last, it sends SMS to the user.

## Step 4: Set request URL for phone verification in Twilio

As of now the system has the capability to send SMS to a user. Now we need to
add capability to receive the SMS and to match the verification code.

First, we need to set up a request URL in Twilio account.

Open twilio account and under **NUMBERS** section/tab, click on your Twilio
number. Then in **Messaging** section, add request URL with **HTTP POST**
method. Add URL like this.

```plaintext
http://your.ngrok.com/phone_verifications/verify_from_message/
```

But to make it work, we need our Rails app on the public internet. There are two
options for this:

1. Deploy Rails app to your VPS or PaaS of choice.
2. Use a tunneling service to take the server running on your development
   machine and make it available at an address on the public internet.

I'm going to use [Ngrok](https://ngrok.com/) tunneling service for the purpose
of this blog. You can check this
[blog](https://www.twilio.com/blog/2013/10/test-your-webhooks-locally-with-ngrok.html)
for more about its usage.

## Step 5: Create phone verification controller

We need one more controller, which will handle phone verification when request
comes from Twilio. When a user replies back with a verification code, it will
trigger request URL through Twilio API. To handle that request, let's add phone
verifications controller.

```plaintext
  $ bin/rails generate controller phone_verifications
```

Add new route in `config/routes.rb`

```plaintext
post "phone_verifications/verify_from_message" => "phone_verifications#verify_from_message"
```

Add following code to the `PhoneVerificationsController`.

```ruby
class PhoneVerificationsController < ApplicationController
  skip_before_action :verify_authenticity_token

  def verify_from_message
    user = get_user_for_phone_verification
    user.mark_phone_as_verified! if user

    render nothing: true
  end

  private

  def get_user_for_phone_verification
    phone_verification_code = params['Body'].try(:strip)
    phone_number            = params['From'].gsub('+1', '')

    condition = { phone_verification_code: phone_verification_code,
                  phone_number: phone_number }

    User.unverified_phones.where(condition).first
  end
end
```

In this controller, we added `skip_before_action :verify_authenticity_token`,
this is because we need to allow twilio request in our Rails app which is
actually an outside request (e.g. not secured request). This means we have
disabled CSRF detection for this controller.

Now look at the `verify_from_message` method, in this method we take phone
verification code and phone number from params hash. Using those data, we find
the user from the database. Once we get the user, then we mark user's phone
number as a verified phone number.

Finally we are set to send business level text messages to the verified phone
number.

This
[blog](https://www.twilio.com/blog/2014/10/twilio-on-rails-part-2-rails-4-app-sending-sms-mms.html)
has more information about how to make secure twilio requests.

## Links

- [Human page](https://www.bigbinary.com/blog/phone-verification-using-twilio)
