Mobile Number Verification Using 2FACTOR in Rails Application

Akashkinwad
3 min readMay 30, 2021

Here we will be using 2FACTOR authentication API to send OTP from Rails application. With free trial account you will get 100 OTP SMA balance. Follow below steps to get started!

Create a new 2FACTOR account

Visit 2FACTOR portal and create your free trial account using your email address and phone number. A unique API key will be generated for your account. You can get this API key in Manage Account > Account Summary section on home page. This API key will be used to call 2FACTOR API’s.

We will be using Net::HTTP to call 2FACTOR API’s.

Create Service class to make API request to 2FACTOR portal from your application.

Create a new file two_factor.rb in app/services/mobile_verification directory and add below code in the two_factor.rb file.
Don’t forget to replace API_KEY. Add API_KEY in environment file for security.

module MobileVerification
class TwoFactor
BASE_URL = 'http://2factor.in/API/V1'
API_KEY = 'Your APi Key here'
class << self
def send_otp(opts: {})
uri = "#{vendor_base_url}/SMS/#{opts[:mobile_number]}/AUTOGEN"
url = URI(uri)
send_request(url)
end
def verify_otp(opts: {})
url = URI("#{vendor_base_url}/SMS/VERIFY/#{opts[:session_id]}/#{opts[:otp]}")
send_request(url)
end
private def send_request(url)
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
response = http.request(request)
rescue => e
render_errors(e.message)
else
render_response(response)
end
def render_response(response)
body = JSON.parse(response.read_body)
if body['Status'] == 'Error' || (body['Status'] == 'Success' && body['Details'] == 'OTP Expired')
render_errors(body['Details'])
else
render_success(body['Details'])
end
end
def render_errors(details)
{ success: false, details: details }
end
def render_success(details)
{ success: true, details: details }
end
def vendor_base_url
BASE_URL + '/' + API_KEY
end
end
end
end

Create API endpoints to send and verify OTP.
Add a new controller method to send and verify OTP in MobileVerificationsController as below:

module Api
module V1
class MobileVerificationsController < ApiController
def send_otp
mobile_number = params.dig(:mobile_verification, :mobile_number)
if mobile_number.present?
response = MobileVerification::TwoFactor.send_otp(
opts: {
mobile_number: mobile_number
}
)
if response[:success]
render json: response, status: :ok
else
render_unprocessable_entity('Failed to send OTP')
end
else
render_unprocessable_entity('mobile number is missing')
end
end
def verify_otp
session_id = params.dig(:mobile_verification, :session_id)
otp = params.dig(:mobile_verification, :otp)
if session_id && otp
response = MobileVerification::TwoFactor(
opts: {
session_id: session_id,
otp: otp
}
)
if response[:success]
render json: response, status: :ok
else
render_unprocessable_entity('Failed to verify OTP')
end
else
render_unprocessable_entity('session_id or otp is missing')
end
end
private def render_unprocessable_entity(message = nil)
render json: { message: message }, status: :unprocessable_entity
end
end
end
end

By default 2FACTOR will generate 6 digits OTP. There are many customization available. Reference for the API documentation is here 2factor-api-docs.

You will get below response back after sending OTP:

{
"Status": "Success",
"Details": "ff9ab5b0-452e-11e7-94da-0200cd936042"
}

And verify OTP will get below response:

{
"Status": "Success",
"Details": "OTP Matched"
}

session_id refers to the ‘Details’ field value returned by the SEND OTP Endpoints. In this case value ff9ab5b0–452e-11e7–94da-0200cd936042 corresponding to Details field is referred to as session_id.

In the verify_otp method you can also perform your custom actions like setting users mobile verified true or same service can be used for user authentication and setting current user in application controller, creating JWT after verifying OTP.

Thats it! Now you can start sending SMS OTP’s from your application.

--

--