Python 2-Factor Authentication: SMS and QR Code Methods

python 2 factor authentication

Introduction

Python 2-Factor Authentication, There’s no denying the fact that this is the age of the incredible threat of cybercrime, so it is imperative that there are extra measures for ensuring protection. 

One of the most effective methods is two-factor authentication (2FA). This method requires customers to provide specific varieties of identity before they can get access to their accounts in addition.

Here is a detailed tutorial as it will take you step to step on how to implement Python 2 Factor Authentication using libraries such as Pyotp for OTP creation, qrcode for QR Codes and SMS via Twilio.

What is Two-Factor Authentication?

2FA is a system that provides a higher level of security for user accounts, requiring absolute authentication in two different ways at any particular time within the process of attempting to log in to the computer.

In a traditional 2FA operation, you need to provide two separate tools or schemes in order to verify your identity.

  • Something You Know: This is generally knowledge that only the user should have, which includes but is not limited to passwords and PINs. It acts as a barrier, which is the first step in the authentication process.
  • Something You Have: This is a tangible item or even an application the user has that assists in further guaranteeing their identity. Typical cases consist of mobile phones when a verification text or a code generated from an application is sent or hardware tokens for one-time passwords.

In its most fundamental form, the previously mentioned combination of interactive elements is what is known as two-factor authentication. It can therefore be said to be multilayered, so the chances of one gaining access if security levels are met are very slim. Not to say that an assailant broke or stole the user’s password, but acquiring the second part would be a problem even for you.

Overview of Our Implementation

Two-factor authentication (2FA) may soon be characterized by features that impose certain security features, such as the use of passwords for one-time use or OTPs.

Python offers quite a number of libraries that ease out the process of generating an OTP, generating QR codes, and sending alerts. This characteristic, combined with the ease of use, makes Python a great choice for developing secure authentication systems. 

In this tutorial, we will develop a Two Factor Authentication (2FA) application in Python that generates a One Time Password (OTP). It is sent to the client’s mobile phone through an SMS message and is only valid for one minute.

In addition to this device, a QR code is also still shown on the device, which can be scanned using any third-party authenticator applications to extend the security even further. 

For this implementation, we will use specific libraries for performing each of the following steps:

  • Generate a Secret Key: Using the Python library, we create a completely unique mystery key as a way to be used to generate One-Time Passwords (OTPs). 
  • Generate a QR Code: With the qrcode library, we generate a QR code that can be scanned by an authenticator app to install 2FA. 
  • Send OTP through SMS: We use the Twilio library to ship the OTP to the consumer’s telephone. 
  • Verify OTP: The pyotp library is once again used to validate the OTP entered through the user.

2FA Development

Before diving into the code, you have to make sure that the subsequent Python libraries are established, pyotp, qrcode, and twilio.

The pyotp library is critical for generating and verifying OTPs, whilst qrcode is used to create QR codes. The twilio library lets in us to send SMS messages.

To install these packages, you have to use the pip command. Open your terminal or command prompt and run the following command:

Bash
$ pip install pyotp qrcode twilio

After the required libraries have been installed, we start off with the coding activity by importing them since they will be used all through the development.

import pyotp
import qrcode
from twilio.rest import Client

These libraries will help us generate OTPs, create QR codes, and send SMS messages.

When it comes to beginning using Twilio, the first step is to configure your twilio configurations. In order to get started, set the variables TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER for your Twilio Account SID, Auth Token, and Twilio phone number, respectively.

After that, you will need to set up the Twilio client with these credentials using the Client class, where you will provide your account SID and Auth token. This configuration will let you make system calls to Twilio’s API.

# Twilio setup
TWILIO_ACCOUNT_SID = 'YOUR_ACCOUNT_SSID'
TWILIO_AUTH_TOKEN = 'YOUR_AUTH_TOKEN'
TWILIO_PHONE_NUMBER = 'YOUR_TWILIO_ACCOUNT_PHONE_NUMBER'

client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

Check on your Twilio account by getting your Twilio account SID, Auth Token, and Twilio Phone Number. Log in for the first time if you do not have and scroll down to the dashboard for your account ID and account authorization token located below the account info section.

Users who have logged in should go to the Dashboard and scroll down in the ‘Account Info’ section of the page to find the AccountSID and AuthToken. Make sure that those credentials are kept very safe since they will be useful in locking into the services offered by Twilio.

def generate_secret():
    totp = pyotp.TOTP(pyotp.random_base32(), interval=60)
    return totp.secret

A function named generate_secret() for time-based one-time passwords (TOTP) is defined, wherein in this function a new secret key is created and returned. For the generation of OTPs, a time-based, one-time password is generated by the pyotp.

TOTP() requires a randomly generated base32 secret, which will last for up to a minute. Then the next step is that the function returns the secret that TOTP needs at a given time to work effectively as a safe time-dependent password.

Our next step is to produce a QR code, which can only be verified using an authenticator application after an OTP has been generated. Using the user’s email address and the TOTP secret, a provisioning URI is created and subsequently converted into a QR code.

The generate_qr_code() function wraps a string with the user’s email and the application name, creates and starts a TOTP object that uses the secret and a time period of 60 seconds, then calls the qrcode library to make the required image.

This image is saved in the script directory as “qrcode.png,” which can then be scanned by an application like Google Authenticator, which can be used to set up OTP-based two-factor authentication for the user.

def generate_qr_code(secret, user_email):
    totp = pyotp.TOTP(secret, interval=60)
    provisioning_uri = totp.provisioning_uri(name=user_email, issuer_name="YourAppName")
    
    qr = qrcode.QRCode(version=1, box_size=10, border=4)
    qr.add_data(provisioning_uri)
    qr.make(fit=True)
    img = qr.make_image(fill='black', back_color='white')
    img.save("qrcode.png")
    print("QR Code saved as 'qrcode.png'.")

Next, we shall proceed to implement a function called send_sms(), which shall use the Twilio API to send an SMS containing an OTP to a designated number following the setup of the OTP QR code.

The function takes in two parameters: the recipient’s number and the one-time password. It creates and sends an SMS utilizing client.messages.create() from an already configured Twilio number with the OTP embedded in the message body.

After sending the message, the function returns with a confirmation showing the unique SID that Twilio assigns to every message for reference.

def send_sms(phone_number, otp):
    message = client.messages.create(
        body=f'Your OTP code is {otp}. It is valid for 1 minute.',
        from_=TWILIO_PHONE_NUMBER,
        to="RECEIVER_PHONE_NUMBER" #replace this with the actual receiver phone number
    )
    print(f'SMS sent to {phone_number}: {message.sid}')

The below code properly describes the process of the verify_otp() method that receives a one-time password(OTP) and checks whether it is valid by comparing it to the secret key.

The implementation in this section starts by creating and initializing a TOTP (time-based, one-time password) object with the provided secret and a valid period of sixty seconds.

Then it verifies if the supplied OTP corresponds to the OTP that the TOTP object is making at the moment. It provides assurance on the time-based codes during authentication and returns. True if the OTP is correct, else returns False when the OTP is not correct.

def verify_otp(secret, otp):
    totp = pyotp.TOTP(secret, interval=60)
    return totp.verify(otp)

Now it is time to wrap up the writing of the script’s meaty part by executing the logic of the script. To begin with, we obtain the user’s mobile phone number and email address.

After that, we create and present the secret key. In respect to this secret, a QR code is created and stored, and the user authenticating the app scans such a Google Authenticator. Then we will use this secret to generate a one-time password (OTP) and send it as a message to the user’s phone.

Then we prompt the user to input the one-time password that was sent and validate its correctness. An error message appears if the OTP is incorrect; otherwise, a confirmation message appears. This completes the secure OTP-based authentication setup and verification procedure.

if __name__ == "__main__":
    user_email = "user@example.com"
    user_phone_number = "+1234567890"  # Replace with the user's phone number
    
    # Generate and display the secret key
    secret = generate_secret()
    print(f"Secret: {secret}")
    
    # Generate and display the QR code
    generate_qr_code(secret, user_email)
    
    # Generate an OTP and send it via SMS
    totp = pyotp.TOTP(secret, interval=60)
    otp = totp.now()
    send_sms(user_phone_number, otp)
    
    # Example OTP verification
    otp_input = input("Enter the OTP from your SMS: ")
    if verify_otp(secret, otp_input):
        print("OTP is valid!")
    else:
        print("Invalid OTP.")

Running Script

Running this code will execute the sequence of commands performing the time-based one-time passwords (TOTP). It initiates the secret key’s existence as well as printing it specifically.

The code then displays a QR code using this secret in the script’s directory and reserves it as “qrcode.png.” The provisioning URI, which has to be used to configure the TOTP on an authenticator app, is however led by a QR code.

python 2 factor authentication
OTP QR Code

The code uses Twilio‘s API to SMS the OTP it to the designated phone number.

python 2 factor authentication

The script requests that the user enter the OTP they were sent at the conclusion, comparing it with the one that was created.

If the OTP entered matches, a confirmation message shows up; if not, an error message indicating that the OTP is invalid appears.

python 2 factor authentication

🧷Explore the complete source code on GitHub


Light
×