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.
⭐ Role para baixo até a seção Informações da conta. Copie o SID da conta e o token de autenticação.
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.
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.
Se uma senha de uso único (OTP) incorreta for inserida, uma caixa de mensagem será exibida indicando que o OTP não corresponde.
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.
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.