How to Add Two-Factor Authentication to a Python Flask Application with Plivo

How to Add Two-Factor Authentication to a Python Flask Application with Plivo

Two-factor authentication (2FA) can play a key role in securing your applications against password data breaches. Authentication with a one-time password (OTP) delivered to your users over SMS is an effective approach to implementing two-factor authentication. Plivo’s premium direct routes guarantee the highest possible delivery rates and the shortest possible delivery times for your 2FA SMS messages. In this blog post, we walk you through a sample implementation of 2FA using the Plivo SMS platform and PHLO, our visual workflow builder.

Prerequisites

Before you get started, you’ll need:

  • A Plivo account — sign up for one for free if you don’t have one already.
  • An SMS-enabled Plivo phone number to send messages to the US and Canada. To search for and rent an available number, go to Phone Numbers > Buy Numbers on the Plivo console.
Buy a New Plivo Number

Create a PHLO to send OTP via SMS

PHLO lets you construct your entire use case and build and deploy workflows visually. With PHLO, you pay only for calls you make and receive, and building with PHLO is free.

To get started, visit PHLO in the Plivo console and click on Create New PHLO. A pop-up window gives you a list of prebuilt templates to start with. Choose Two-Factor Authentication and click Create Application to create a PHLO with the prebuilt components to build a workflow that can manage sending the OTP via SMS, with failover to use a phone call to deliver the OTP as a text-to-speech (TTS) message.


Use the PHLO in a Flask application

We have a demo application available for this in our GitHub repository that you can clone to see how the implementation works.

  • Clone the repository from GitHub.
$ git clone https://github.com/plivo/2fa-python-demo.git
  • Change your working directory to 2fa-python-demo.
$ cd 2fa-python-demo
  • Install the dependencies using the requirements.txt file.
$ pip install -r requirements.txt
  • Edit the settings.py file. Replace the PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN, PLIVO_NUMBER, and PHLO_ID placeholders with your own values.
Configuration file

Note: Enter your phone number in E.164 format.

Generate the OTP

Generate an exclusive six-digit authentication code. To create the OTP, use the time-based OTP generation algorithm. Here’s how it’s done in Python.

def generate_code(self):
    code = random.choice(range(100000, 999999))  # generating 6 digit random code
    return code

Send OTP via SMS or a phone call

A single function helps us to trigger the PHLO to send SMS messages and make calls; the rest of the work is done by PHLO. Use the mode argument to tell PHLO whether to trigger a call or an SMS message by passing the value “sms” or “call.”

def send_verification_code_phlo(self,dst_number,code,mode):
    payload = {
        "from": self.app_number,
        "to": dst_number,
        "otp": code,
        "mode": mode,
    }
    try:
        phlo = self.client_phlo.phlo.get(self.phlo_id)
        response = phlo.run(**payload)
        return response
    except exceptions as e:
        print(e)
        return ("Error encountered", 400)

Verify the OTP

After the user enters the OTP they received on their handset, this Python code verifies it.

@app.route("/verify/<number>")
    def verify(number):
        """
        verify(number) accepts a number and initiates verification for it.
        """
        try:
            code = current_app.p2fa.generate_code()
            if app.config["PHLO_ID"] == "":
                {
                    current_app.p2fa.send_verification_code_sms(
                        number,
                        f'Your verification code is "{code}".
                        Code will expire in 1 minute. ',
                    )  # String should be less than 160 chars
                }
            else:
                {current_app.p2fa.send_verification_code_phlo(number, code, "sms")}
            current_app.redis.setex(
                "number:%s:code" % number, 60, code
            )  # Verification code is valid for 1 min
            return jsonify({"status": "success", "message": "verification initiated"})
        except:
            return ("Error encountered", 400)
    

Test

To run the application, start Redis using the redis-server command. Start Flask, the Python web framework module, by typing flask run. Flask will display the URL and port number on which it’s running. Click on that link to run the sample application in your browser.

On the browser page, choose your country and enter your mobile number, then click on Send Verification Code. Check your mobile phone — you should get an SMS message with an OTP code. Enter the code in the browser form and click Verify, and the application will confirm that you’re verified.

What if you don’t get the SMS message you were expecting, or you wait too long to enter the value you received? The application gives you a link so you can use a phone call as a fallback OTP channel. Click on “Didn’t receive sms? Call me.” You should then receive a call, and when you answer it, you’ll hear a text-to-speech message that gives you an OTP code, which you can use in the form for verification.

Simple and reliable

Edit the sample application to see how simple it was to code. Our simple APIs work in tandem with our comprehensive global network. Plivo’s premium direct routes guarantee the highest possible delivery rates and the shortest possible delivery times for your 2FA SMS and voice messages. See for yourself — sign up for a free trial account.

The State of Marketing in 2024

HubSpot's Annual Inbound Marketing Trends Report

Frequently asked questions

No items found.
footer bg

Subscribe to Our Newsletter

Get monthly product and feature updates, the latest industry news, and more!

Thank you icon
Thank you!
Thank you for subscribing
Oops! Something went wrong while submitting the form.

POSTS YOU MIGHT LIKE