<

Getting Started with Two Factor Authentication

Password leaks are commonplace today, and two-factor authentication plays a key role in securing your application against password data breaches.

Authentication with a ‘One-Time Password’ (OTP) delivered to your user over SMS is the most effective and common approach to implementing two-factor authentication today.

However, poor delivery rates for your OTP messages can have a direct impact on your product’s conversion metrics. Plivo’s premium direct routes guarantee highest possible delivery rates and the shortest possible delivery times for your 2FA SMS messages.

In this guide, we will go over the steps involved in setting up an SMS based Two Factor Authentication system.

Step 1: Password Based Authentication

The first step in a 2FA process is plain old username/password based authentication.

If an unauthenticated user requests a protected resource on your application server, present the user with a login screen on your application front end (mobile / web).

We shall move to the second step of the 2FA process only if the username/password entered by the user is found to be correct.

Step 2: Sending SMS With OTP

In this step, we will –

  1. Generate a unique four or six digit verification code (OTP).
  2. Send SMS with OTP to the user’s registered mobile number using Plivo’s Send Message API.

Let’s look at the code to accomplish the above mentioned points. Note that the code samples in this tutorial are in Python. We shall use the Time Based OTP (TOTP) generation algorithm to generate the OTP. Read more about TOPT here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pyotp  # 'pyotp' is an open source package to generate and validate OTPs. Learn more about pyotp here - https://github.com/pyotp/pyotp.
import plivo  # You can download the latest version of Plivo's server-side SDK here -
import unicodedata
import datetime


# We shall use the Time-Based OTP (TOTP) generation algorithm.
# For simplicity, we are using 'pyotp.random_base32()' to generate a random secret key.
# We suggest reading your secret key from a config file.
totp = pyotp.TOTP(pyotp.random_base32())

plivo_auth_id = "Your AUTH_ID"
plivo_auth_token = "Your Auth_TOKEN"

# Initializing Plivo rest client.
p = plivo.RestAPI(auth_id, auth_token)


def send_otp(source_number, destination_number):
    params = {
        'src': source_number, # Sender's phone number with country code
        'dst' : destination_number, # The end user's phone Number with country code
        'text' : str(totp.now()) + " is your <App Name> verification code." # Your SMS Text Message
    }

    response = p.send_message(params)

Step 3: Verifying OTP Entered By User

In the previous step, we sent an OTP to the user’s registered phone number using Plivo Send Message API. The user should receive the SMS with their OTP within a couple of seconds.

To authenticate the user, pass the OTP entered by the user to your application server.

Let’s take a look at the server side code that verifies the OTP entered by the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def verify_otp(user_input):
    current_time = datetime.datetime.now()
    """
    Compare the user entered OTP against valid OTPs for the last 60 seconds.
    """
    for i in range(-60, 1):
        if strings_equal(str(user_input), str(totp.at(current_time, i))):
            return True
        return False

def strings_equal(s1, s2):
    """
    Timing-attack resistant string comparison.
    Normal comparison using == will short-circuit on the first mismatching
    character. This avoids that by scanning the whole string, though we
    still reveal to a timing attack whether the strings are the same
    length.
    """
    s1 = unicodedata.normalize('NFKC', s1)
    s2 = unicodedata.normalize('NFKC', s2)
    return compare_digest(s1, s2)