Contents

Como construir um sistema de verificação OTP usando Python

Os sistemas de verificação OTP (One-Time Password) desempenham um papel fundamental na garantia da segurança, mesmo quando as senhas são comprometidas. Esses sistemas eliminam a necessidade de memorizar várias senhas, adicionando uma camada adicional de proteção contra acesso não autorizado. Além disso, eles minimizam o risco de serem vítimas de golpes de phishing, fornecendo um código exclusivo cada vez que é feita uma tentativa de login, impedindo assim possíveis tentativas de cibercriminosos de entrar por meios fraudulentos.

A implementação de um mecanismo de autenticação de senha única (OTP) utilizando Python pode ser alcançada criando um sistema que transmite um código OTP para um número de telefone celular designado. O OTP terá uma vida útil limitada de dois minutos e os privilégios de acesso serão revogados ao inserir um PIN incorreto em três tentativas consecutivas.

Instale os módulos Tkinter, Twilio e Random

O Tkinter oferece uma oportunidade para os usuários gerarem interfaces gráficas de usuário em seus desktops por meio do fornecimento de diversos elementos visuais, como botões, rótulos e campos de entrada de texto, facilitando assim o processo de desenvolvimento de aplicativos de software.

A integração Twilio permite a incorporação perfeita de recursos de comunicação, incluindo SMS, MMS, chamadas de voz e autenticação em um aplicativo. A plataforma possui uma arquitetura baseada em nuvem juntamente com atributos avançados, como alocação de números, layouts de mensagens e registro de chamadas.

Para instalar os pacotes Twilio e Tkinter via interface de linha de comando, execute a seguinte instrução em seu terminal:

 pip install twilio tk 

O módulo Random em Python fornece um meio de gerar números pseudo-aleatórios por meio de várias funções que permitem aos usuários executar tarefas como produzir números inteiros aleatórios dentro de um intervalo especificado, selecionar itens aleatoriamente de um determinado conjunto e embaralhar a ordem dos elementos em uma lista. Este módulo versátil permite que os desenvolvedores criem simulações de jogadas de dados, implementem geradores de senha aleatórios e até mesmo embaralham listas com facilidade.

Gere a API do Twilio e obtenha um número de telefone

Para utilizar a funcionalidade One-Time Password (OTP) do Twilio e receber solicitações OTP em seu dispositivo móvel, é necessário obter as credenciais de autenticação necessárias e associá-las a um número de telefone Twilio exclusivo. Isso pode ser feito seguindo as seguintes etapas:

⭐ Inscreva-se em uma conta Twilio e visite o console Twilio.

⭐ Role para baixo e clique no botão Obter número de telefone. Copie o número de telefone gerado. /pt/images/get-a-phone-number-from-console.jpg

⭐ Role para baixo até a seção Informações da conta. Copie o SID da conta e o token de autenticação. /pt/images/copy-twilio-credentials-from-console.jpg

Construindo a Estrutura do Aplicativo

O código-fonte completo para a construção de um sistema de verificação de senha única (OTP) utilizando Python está disponível neste

Importe os módulos necessários e estabeleça as credenciais de autenticação. Configure o cliente Twilio como um gateway para solicitações de API, especificando uma duração de expiração de dois minutos.

Para criar uma instância da classe OTPVerification, primeiro precisamos defini-la especificando seus atributos no código Python. Isso envolve definir os construtores que serão responsáveis ​​por configurar o estado inicial do objeto, bem como quaisquer tarefas de inicialização necessárias, como alocar memória ou abrir janelas. Por exemplo, pode-se implementar um construtor como este:rubyclass OTPVerification:def init (self):self.default_values ​​=# alguns valores padrão aqui…# Inicialize a janela raiz e defina suas propriedadesself.root_window=tk.Tk()self.root_window.title(“Verificação OTP”)self.root_window.geometry(“500x400+10

 import tkinter as tk
from tkinter import messagebox
from twilio.rest import Client
import random
import threading
import time

account_sid = "YOUR_ACCOUNT_SID"
auth_token = "YOUR_AUTH_TOKEN"
client = Client(account_sid, auth_token)
expiration_time = 120

class OTPVerification:
    def __init__(self, master):
        self.master = master
        self.master.title('OTP Verification')
        self.master.geometry("600x275")
        self.otp = None
        self.timer_thread = None
        self.resend_timer = None
        self.wrong_attempts = 0
        self.locked = False
        self.stop_timer = False
 

Versão em inglês elegantemente elaborada:pythonIncorpore um design visualmente atraente criando três botões fáceis de usar para enviar, reenviar e verificar uma senha de uso único (OTP). Designe o elemento pai de cada botão, prescreva conteúdo textual conciso, mas informativo, e atribua comandos funcionais distintos ao clicar. Empregue o método versátil pack para organizar esses elementos em um layout organizado e equilibrado. Essa abordagem garante que os usuários possam acessar e interagir facilmente com a funcionalidade necessária, mantendo uma interface visual coesa.

         self.label1 = tk.Label(self.master,
                                text='Enter your mobile number:',
                               font=('Arial', 14))
        self.label1.pack()

        self.mobile_number_entry = tk.Entry(self.master,
                                             width=20,
                                            font=('Arial', 14))
        self.mobile_number_entry.pack()

        self.send_otp_button = tk.Button(self.master,
                                          text='Send OTP',
                                          command=self.send_otp,
                                         font=('Arial', 14))
        self.send_otp_button.pack()

        self.timer_label = tk.Label(self.master,
                                     text='',
                                     font=('Arial', 12, 'bold'))
        self.timer_label.pack()

        self.resend_otp_button = tk.Button(self.master,
                                            text='Resend OTP',
                                            state=tk.DISABLED,
                                            command=self.resend_otp,
                                           font=('Arial', 14))
        self.resend_otp_button.pack()

        self.label2 = tk.Label(self.master,
                                text='Enter OTP sent to your mobile:',
                               font=('Arial', 14))
        self.label2.pack()

        self.otp_entry = tk.Entry(self.master,
                                   width=20,
                                  font=('Arial', 14))
        self.otp_entry.pack()

        self.verify_otp_button = tk.Button(self.master,
                                            text='Verify OTP',
                                            command=self.verify_otp,
                                           font=('Arial', 14))
        self.verify_otp_button.pack() 

Construindo a Funcionalidade do Aplicativo

Para implementar uma operação simultânea para contagem regressiva de um cronômetro, podemos definir um novo método chamado start\_timer() que iniciará uma thread secundária para executar a função timer\_countdown(). Essa abordagem permite que ambos os processos sejam executados simultaneamente sem interferir no fluxo de execução um do outro.

     def start_timer(self):
        self.timer_thread = threading.Thread(target=self.timer_countdown)
        self.timer_thread.start() 

Incorpore o trecho de código fornecido em seu projeto, incluindo-o em uma função chamada timer\_countdown(). Esta função deve inicializar uma variável para registrar o horário de início, executar um loop infinito que atualize continuamente o tempo decorrido e restante com base no horário atual e os compare com valores predefinidos. O loop cessará quando a condição especificada pelo valor booleano de stop\_timer for atendida. Além disso, se o tempo restante calculado cair abaixo ou chegar a zero, uma mensagem de erro será exibida indicando que a senha de uso único (OTP) expirou.

Ative o botão “reenviar OTP”, certifique-se de que a senha de uso único esteja definida como nula e conclua o processo. Como alternativa, determine os minutos e segundos restantes até a expiração, mostre esse valor no rótulo do cronômetro e faça uma pausa de um único segundo.

     def timer_countdown(self):
        start_time = time.time()
        while True:
            current_time = time.time()
            elapsed_time = current_time - start_time
            remaining_time = expiration_time - elapsed_time
            if self.stop_timer:
                break
            if remaining_time <= 0:
                messagebox.showerror('Error', 'OTP has expired.')
                self.resend_otp_button.config(state=tk.NORMAL)
                self.otp = None
                break
            minutes = int(remaining_time//60)
            seconds = int(remaining_time % 60)
            timer_label = f'Time Remaining: {minutes:02d}:{seconds:02d}'
            self.timer_label.config(text=timer_label)
            time.sleep(1) 

se a conta estiver bloqueada, exiba uma mensagem apropriada; caso contrário, recupere o número de telefone da entrada do usuário, execute a validação nos dígitos inseridos e crie uma senha de uso único (OTP). Em seguida, utilize o serviço de gateway SMS para transmitir o OTP gerado para o número de telefone especificado. Em seguida, mostre um diálogo de confirmação, inicie um cronômetro de contagem regressiva, desative todos os botões na interface, elimine qualquer entrada anterior e certifique-se de que nenhuma outra ação seja possível até que um OTP válido seja fornecido pelo usuário.

     def send_otp(self):
        if self.locked:
            messagebox.showinfo('Account Locked', 'Your account is locked. Try again later.')
            return
        mobile_number = self.mobile_number_entry.get()
        if not mobile_number:
            messagebox.showerror('Error', 'Please enter your mobile number.')
            return

        self.otp = random.randint(1000, 9999)
        message = client.messages.create(
            body=f'Your OTP is {self.otp}.',
            from_='TWILIO_MOBILE_NUMBER',
            to=mobile_number
        )
        messagebox.showinfo('OTP Sent', f'OTP has been sent to {mobile_number}.')
        self.start_timer()
        self.send_otp_button.config(state=tk.DISABLED)
         self.resend_otp_button.config(state=tk.DISABLED)
         self.otp_entry.delete(0, tk.END)

Incorporando o texto fornecido, podemos refinar as instruções para a função resendOTP() da seguinte forma: javascript//Reenviar funcionalidade do recurso OTPfunção resendOTP(phoneNumber) {//Verifique se a conta já foi verificada ou não deixe userVerified=false;//Descubra se há uma sessão existente comparando o número de telefone com o ID do dispositivo em Firestoreconst userSessions=await getUserSessions();const docRef=doc(firestore, “users”, phoneNumber);const userData=await getDoc(docRef);if ( userData && userData.exists()) {//Os dados do usuário existem no Firestore, então temos que verificar se eles

     def resend_otp(self):
        if self.locked:
            messagebox.showinfo('Account Locked', 'Your account is locked. Try again later.')
            return
        mobile_number = self.mobile_number_entry.get()
        if not mobile_number:
            messagebox.showerror('Error', 'Please enter your mobile number.')
            return

        self.otp = random.randint(1000, 9999)
        message = client.messages.create(
            body=f'Your OTP is {self.otp}.',
            from_='TWILIO_MOBILE_NUMBER',
            to=mobile_number
        )
        messagebox.showinfo('OTP Sent', f'New OTP has been sent to {mobile_number}.')
        self.start_timer()
        self.resend_otp_button.config(state=tk.DISABLED) 

Existe um procedimento denominado “verify\_otp()” em nosso sistema, que obtém a senha de uso único (OTP) da entrada do usuário. Se nenhum OTP foi registrado anteriormente pelo usuário, uma instrução será exibida solicitando a criação de um novo OTP. Uma vez realizada esta tarefa, o programa compara o OTP recém-gerado com a versão salva para validar sua autenticidade. Após a comparação bem-sucedida, uma mensagem indicando que o processo de verificação foi bem-sucedido aparecerá na tela, juntamente com a cessação de quaisquer medições de tempo em andamento e encerramento do aplicativo. No entanto, caso ocorram várias tentativas incorretas de inserir o OTP correto, bloquearemos a conta do usuário após a terceira tentativa malsucedida, de acordo com os critérios especificados.

     def verify_otp(self):
        user_otp = self.otp_entry.get()
        if not user_otp:
            messagebox.showerror('Error', 'Please enter OTP.')
            return
        if self.otp is None:
            messagebox.showerror('Error', 'Please generate OTP first.')
            return
        if int(user_otp) == self.otp:
            messagebox.showinfo('Success', 'OTP verified successfully.')
            self.stop_timer = True
             exit()
        else:
            self.wrong_attempts \+= 1
            if self.wrong_attempts == 3:
                self.lock_account()
            else:
                messagebox.showerror('Error', 'OTP does not match.') 

Aqui está uma maneira alternativa de formular as instruções fornecidas de maneira mais refinada: javascript//Defina uma função chamada’lock_account’com as seguintes ações: function lock_account() {//Configure o status da conta a ser bloqueado definindo o valor booleano como truesetAccountLockStatus(true);//Exibe uma mensagem indicando que a conta agora está bloqueada, usando dicas visuais apropriadas, como alteração de texto ou ícone colorupdateAccountLabel(“Conta bloqueada”);//Desativa temporariamente todos os elementos interativos na página, incluindo campos de formulário , botões, links, etc., usando classes CSS apropriadas ou código JavaScriptdisableAllInteractiveElements();//Interrompa quaisquer cronômetros em execução ou animações associadas à conta e reinicie

     def lock_account(self):
        self.locked = True
        self.label1.config(text='Account Locked')
        self.mobile_number_entry.config(state=tk.DISABLED)
        self.send_otp_button.config(state=tk.DISABLED)
        self.timer_label.config(text='')
        self.resend_otp_button.config(state=tk.DISABLED)
        self.label2.config(text='')
        self.otp_entry.config(state=tk.DISABLED)
        self.verify_otp_button.config(state=tk.DISABLED)
        self.stop_timer = True
         countdown_time = 10 * 60
         self.start_countdown(countdown_time) 

Incorpore o trecho de código fornecido na interface do usuário do seu aplicativo como um recurso interativo. Essa funcionalidade permite que os usuários iniciem uma contagem regressiva para a suspensão de sua conta quando estiverem perto de atingir o limite de pontos negativos necessários para o encerramento. O método será acionado se o tempo restante cair abaixo de um determinado valor, como zero, ponto em que ele redefine a conta. No entanto, se ainda faltar algum tempo para o limite ser atingido, o sistema exibe uma mensagem indicando que o programa bloqueou a conta e orienta o usuário a aguardar o tempo restante antes de tentar novamente.

     def start_countdown(self, remaining_time):
        if remaining_time <= 0:
            self.reset_account()
            return

        minutes = int(remaining_time//60)
        seconds = int(remaining_time % 60)
        timer_label = f'Account Locked. Try again in: {minutes:02d}:{seconds:02d}'
        self.timer_label.config(text=timer_label)
        self.master.after(1000, self.start_countdown, remaining_time-1) 

O código fornecido define uma função chamada reset\_account() , que se destina a restaurar o estado de todos os widgets e variáveis ​​para suas configurações iniciais.

     def reset_account(self):
        self.locked = False
        self.wrong_attempts = 0
        self.label1.config(text='Enter your mobile number:')
        self.mobile_number_entry.config(state=tk.NORMAL)
        self.send_otp_button.config(state=tk.NORMAL)
        self.timer_label.config(text='')
        self.resend_otp_button.config(state=tk.DISABLED)
        self.label2.config(text='Enter OTP sent to your mobile:')
        self.otp_entry.config(state=tk.NORMAL)
        self.verify_otp_button.config(state=tk.NORMAL)
        self.stop_timer = False 

Incorpore o trecho de código fornecido em um script Python para estabelecer uma janela raiz na estrutura Tkinter instanciando um objeto de sua respectiva classe. Posteriormente, execute o aplicativo Tkinter usando esta instância criada.

 if __name__ == '__main__':
    root = tk.Tk()
    otp_verification = OTPVerification(root)
    root.mainloop() 

Exemplo de Saída de Verificação Usando OTP

Ao executar o módulo de verificação de senha única (OTP), uma interface aparecerá solicitando que você insira seu número de celular junto com o código do país aplicável. Depois de inserido, clique no símbolo de tabulação’Enviar OTP’. Uma notificação confirmando o envio bem-sucedido do OTP será exibida; além disso, este botão permanecerá inativo por aproximadamente 120 segundos. Consequentemente, examine seu aparelho para o OTP recebido e insira-o dentro do prazo especificado.

/pt/images/start-screen-of-otp-verification-program.jpg

Ao inserir corretamente a senha única dentro do prazo alocado, uma indicação de verificação bem-sucedida é transmitida por meio de uma mensagem, resultando subsequentemente no encerramento do programa. Por outro lado, se a duração prescrita expirar sem inserir o código correto, uma caixa de mensagem alertará o usuário de que o OTP expirou. Ao clicar na opção para reenviar o OTP, um novo token de autenticação pode ser gerado e transmitido ao dispositivo móvel do usuário para posterior processamento.

/pt/images/correct-otp-enter-on-otp-verification-program-1.jpg

Se uma senha de uso único (OTP) incorreta for inserida, uma caixa de mensagem será exibida indicando que o OTP não corresponde.

/pt/images/wrong-otp-enter-on-otp-verification-program.jpg

No caso de uma senha de uso único (OTP) incorreta ser inserida em três ocasiões distintas, todos os campos do formulário ficarão inoperantes e a conta do usuário será suspensa temporariamente por um período de dez minutos como medida de segurança para evitar tentativas de acesso não autorizado.

/pt/images/account-locked-screen-on-otp-verification-program-2.jpg

Usando Twilio com Python

Utilizando os recursos do Twilio, pode-se construir um mecanismo de alerta de mensagem de texto versátil para lidar com diversas ocorrências. Isso inclui integrá-lo a dispositivos da Internet das Coisas (IoT) para enviar notificações quando parâmetros específicos transcendem ou ficam aquém dos limites predeterminados, bem como quando uma entrada não autorizada é detectada. Além disso, medidas avançadas de segurança, como processos de verificação em duas etapas, podem ser implementadas em conjunto com o Twilio para estabelecer sistemas de login robustos. Além disso, a plataforma permite o desenvolvimento de chatbots no popular aplicativo de mensagens WhatsApp, juntamente com lembretes de compromissos automatizados.

Além de sua função principal, pode-se empregar a plataforma mencionada para vários fins, como autenticação de número de telefone, esforços promocionais, disseminação de questionários e obtenção de comentários. Ao conceber qualquer solução de software, é crucial permanecer ciente das despesas associadas à API do Twilio para evitar taxas imprevistas.