Two-factor authentication using Python

    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.

    This guide shows how to set up SMS-based two-factor authentication using either PHLO or traditional API development. PHLO lets you create and deploy workflows from an intuitive graphical canvas in few clicks.

    To implement Two-factor use case, you can create and deploy a PHLO with a few clicks on the PHLO canvas. PHLO also lets you visually construct your entire use-case. With PHLO, you only pay for SMS you send/receive, and building with PHLO is free.

    Implementation

    In this section, we will guide you to create a PHLO to implement Two-factor use-case.

    Prerequisites

    • Plivo Auth Id and Auth Token: You will find your Plivo Auth Id and Auth Token on the home screen of your Plivo Console. Click here to sign-up for a Plivo account if you haven’t already!

      Find Your Auth Credentials on Plivo Console

    • Plivo Phone Number(Optional): To send messages to the United States and Canada, you must have a Plivo phone number that supports SMS. Numbers can be purchased from the Numbers section of your Plivo Console and use the same as the source number/from number for the outbound SMS. This number will also help you receive incoming SMS as you must have a SMS-enabled Plivo phone number to do the same. Please note that you can also purchase numbers using the Numbers API.

      Buy a New Plivo Number

    • Github account(Optional): To get the code from the repository, clone it. Otherwise, since the repository is open to the public, we can download the code and run it locally.

    Create the PHLO

    With PHLO, you can quickly create a workflow that suits your use case. To use PHLO, make sure to register and log on to Plivo Console. There is already a prototype for this use-case; all you need to do is select the PHLO and give it a friendly name.

    PHLO Setup

    Set up Your Python Dev Environment

    You must set up and install Python and Plivo’s Python SDK to make a bulk call. Here’s how.

    Install Python

    Operating SystemInstructions
    OS X & LinuxYou would already have Python installed, you can check this by running the command python --version in the terminal
    WindowsTo install Python on Windows you can follow the instructions from here.

    Set Up the Demo app locally

    • 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. You can use the below command.
     $ pip install -r requirements.txt
    • Change the placeholders in the settings.py file. You should replace the PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN, PLIVO_NUMBER & PHLO_ID placeholders. Configuration file
    Note: Enter your phone number in E.164 format.
    • Turn on the redis server by entering the following command in your terminal
     $ redis-server

    Redis Server

    • The different steps that are involved in this app are as follows:

    Step 1 : Generate the OTP

    Generate an exclusive six-digit authentication code (OTP). To create the OTP, we will use the Time Based OTP generation algorithm. here’s how it’s done in Python.

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

    Step 2 : Send SMS & Make a call

    A single function help us to trigger to Send SMS and Make call via PHLO and the rest is done by the PHLO in your console. The main argument which tells PHLO to trigger call or an SMS is mode the values passed within are sms & call.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    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)
    

    Step 3 : Verify the OTP

    Once the user enters the OTP received to their handset, the code will be verified and here’s how it’s done in Python.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    @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 and Validate

    In order to run the app, run the following command.

    $ flask run
    

    You check the app in action on https://3b3e783f.ngrok.io/

    The finished app should look like this. Two-Factor Authentication

    Note: If you are using a Plivo Trial account for this example, you can only send SMS to phone numbers that have been verified with Plivo. Phone numbers can be verified at the Sandbox Numbers page.

    To implement two Factor Authentication use-case in the traditional API way, you can refer to the instructions in the below section to begin your implementation.

    Implementation

    In this section, we will guide you in setting up an app using Plivo’s API to implement two factor authentication. First, let’s make sure you meet these prerequisites before we dive into the code.

    Prerequisites

    • Plivo Auth Id and Auth Token: You will find your Plivo Auth Id and Auth Token on the home screen of your Plivo Console. Click here to sign-up for a Plivo account if you haven’t already!

      Find Your Auth Credentials on Plivo Console

    • Plivo Phone Number(Optional): To send messages to the United States and Canada, you must have a Plivo phone number that supports SMS. Numbers can be purchased from the Numbers section of your Plivo Console and use the same as the source number/from number for the outbound SMS. This number will also help you receive incoming SMS as you must have a SMS-enabled Plivo phone number to do the same. Please note that you can also purchase numbers using the Numbers API.

      Buy a New Plivo Number

    • Github account(Optional): To get the code from the repository, clone it. Otherwise, since the repository is open to the public, we can download the code and run it locally.

    Set up Your Python Environment

    You must set up and install Python>=3

    Operating SystemInstructions
    OS X & LinuxYou would already have Python installed, you can check this by running the command python --version in the terminal
    WindowsTo install Python on Windows you can follow the instructions from here.

    Set Up the Demo app locally

    • Clone the repository from Github
     $ https://github.com/plivo-dev/2fa-python-demo
    • Change your working directory to 2fa-python-demo
     $ cd 2fa-python-demo
    • Install the dependencies using the requirements.txt file. You can use the below command.
     $ pip install -r requirements.txt
    • Change the placeholders in the settings.py file. You should replace the PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN & PLIVO_NUMBER placeholders. Configuration file
  • Note: Enter your phone number in E.164 format.
  • Note: In case if you wouldn't like to you use PHLO then update the value as PHLO_ID = "".
    • Turn on the redis server by entering the following command in your terminal
     $ redis-server

    Redis Server

    • The different steps that are involved in this app are as follows:

    Step 1 : Generate the OTP

    Generate an exclusive six-digit authentication code (OTP). To create the OTP, we will use the Time Based OTP generation algorithm. here’s how it’s done in Python.

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

    Step 2 : Send SMS message with OTP

    Send SMS with OTP to the user’s registered mobile number using Plivo’s Send Message API.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    def send_verification_code_sms(self, dst_number: str, message):
            """
            `send_verification_code` accepts destination number
            to which the message that has to be sent.
    
            The message text should contain a `__code__` construct
            in the message text which will be
            replaced by the code generated before sending the SMS.
    
            :param: dst_number
            :param: message
            :return: verification code
            """
            try:
                response = self.client.messages.create(
                    src=self.app_number, dst=dst_number, text=message
                )
                print(response)
                return response
            except exceptions as e:
                print(e)
                return "Error encountered", 400
    

    Step 3 : Make a phone call with OTP(Failover)

    When messages aren’t deliverable for a variety of reasons, the user can choose voice OTP, and here’s how it’s done in Python.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    def send_verification_code_voice(self, dst_number, code):
    try:
            response = self.client.calls.create(
                    from_=self.app_number,
                    to_=dst_number,
                    answer_url=f"https://twofa-answerurl.herokuapp.com/answer_url/{code}",
                    answer_method="GET",
                )
                return response
            except exceptions as e:
                print(e)
                return "Error encountered", 400
    

    Step 4 : Verify the OTP

    Once the user enters the OTP received to their handset, the code will be verified and here’s how it’s done in Python.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    @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 and Validate

    In order to run the app, run the following command.

    $ flask run
    

    You check the app in action on https://3b3e783f.ngrok.io/

    The finished app should look like this. Two-Factor Authentication

    Note: If you are using a Plivo Trial account for this example, you can only send SMS to phone numbers that have been verified with Plivo. Phone numbers can be verified at the Sandbox Numbers page.