[英]how to add otp authentication in django login page
首先,输入并提交电子邮件(用户名)后,login.html 应要求“输入 OTP”。 如果用户存在,则使用用户表检查此用户名。 如果用户存在,它应该向为此用户实例注册的手机发送 OTP。 进入 OTP 后,用户应收到适当的消息以重置密码或进入主页。 我不想使用 django-otp 应用程序。 到目前为止我所做的:在 django 帐户/注册/模板/登录。html
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/login.css" %}">
{{ form.media }}
{% endblock %}
{% block bodyclass %}{{ block.super }} login{% endblock %}
{% block usertools %}{% endblock %}
{% block nav-global %}{% endblock %}
{% block content_title %}{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block content %}
{% if form.errors and not form.non_field_errors %}
<p class="errornote">
{% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
</p>
{% endif %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="errornote">
{{ error }}
</p>
{% endfor %}
{% endif %}
<div id="content-main">
{% if user.is_authenticated %}
<p class="errornote">
{% blocktrans trimmed %}
You are authenticated as {{ username }}, but are not authorized to
access this page. Would you like to login to a different account?
{% endblocktrans %}
</p>
{% endif %}
<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
<div class="form-row">
{{ form.username.errors }}
{{ 'Email:' }} {{ form.username }}
</div>
<div class="form-row">
{{ form.password.errors }}
<!-- {{ form.password.label_tag }} {{ form.password }} -->
<input type="hidden" name="next" value="{{ next }}">
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
{% comment %}
<div class="password-reset-link">
<a href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
</div>
{% endcomment %}
{% endif %}
<div>
{% trans 'Enter OTP' %}</a>
<input type="integer" name="otp" value="{{ otp }}">
</div>
<div class="submit-row">
<label> </label><input type="submit" value="{% trans 'Log in' %}">
</div>
</form>
</div>
{% endblock %}
认证表格:
from django import forms
from django.db.models import IntegerField
from django.contrib.auth.forms import AuthenticationForm, UsernameField
class AuthenticationForm(AuthenticationForm):
class Meta:
model = User
fields = '__all__'
def __init__(self, *args, **kwargs):
super(AuthenticationForm, self).__init__(*args, **kwargs)
for field in self.fields.values():
field.error_messages = {'required':'{fieldname} is required'.format(
fieldname=field.label)}
username = UsernameField(
label='Email',
widget=forms.TextInput(attrs={'autofocus': True})
)
otp = IntegerField()
myauthentication后端代码:
from django.contrib.auth.backends import ModelBackend, UserModel
from django.db.models import Q
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.contrib.auth.models import User, Group
from myapp.models import *
from django.http import *
from datetime import datetime
from django.urls import reverse
from django.utils.translation import ugettext as _
from myapp.forms import AuthenticationForm
import pyotp
from rest_framework.response import Response
from rest_framework.views import APIView
import base64
def generateKey(phone):
return str(phone) + str(datetime.date(datetime.now())) + "Some Random Secret Key"
class EmailBackend(ModelBackend):
#@staticmethod
def authenticate(self, request, username=None, password=None, **kwargs):
mMobile = None
user = None
form = AuthenticationForm(request=request, data=request.GET)
if request.GET:
try:
#to allow authentication through phone number or any other
#field, modify the below statement
user = UserModel.objects.get(
Q(username__iexact=username) | Q(email__iexact=username))
except UserModel.DoesNotExist:
print('iiii')
UserModel().set_password(password)
except MultipleObjectsReturned:
print(222222)
user = User.objects.filter(email=username).order_by('id').first()
else:
if user.check_password(password) and self.user_can_authenticate(
user):
form = AuthenticationForm(request=request, data=request.POST)
if form['username']:
try:
mMobile = Mailbox.objects.get(email=form['username'].value())
#print(user,mMobile, 'uuu-mmmm', dir(mMobile))
except Exception as e:
print(e)
#return user
if mMobile:
mMobile.counter += 1 # Update Counter At every Call
mMobile.save() # SamMove the data
print(mMobile.mobile)
keygen = generateKey(mMobile.mobile)
# Key is generated
key = base64.b32encode(keygen.encode())
OTP = pyotp.HOTP(key)
motp = (OTP.at(mMobile.counter))
print(motp, 'oooottttpp')
if request.POST:
if str(motp) == form.data['otp']:
print(form.data['otp'],'ddddd')
return user
else:
return
return
# Using Multi-Threading send the OTP Using Messaging
# Services like Twilio or Fast2sms
#return user
else:
return user
def get_user(self, user_id):
try:
user = UserModel.objects.get(pk=user_id)
except UserModel.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
问题:在输入用户名并提交时,它应该发送 otp 短信。 现在它在提交表单时发送 otp。 如何准确地结合这个,其中登录表单可以重新提交 2 次? 使用 django 3.1、postgresql 数据库。 我需要确切的代码我从这里使用过的一些部分,如 otp 生成:[https://github.com/Akash16s/OTP-in-django][1]
[1]: https://github.com/Akash16s/OTP-in-django感觉卡住了。 go怎么讲?
我认为你应该看看django_otp
,如果你不想使用那个 package,那么看看代码: https://github.com/django-otp/django-otp
另请查看此博客文章,它可能有用: https://medium.com/@ksarthak4ever/django-two-factor-authentication-2ece42748610
这就是我使用 models.py 的方式
下面是 model.py
class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank =True, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, null=True)
name = models.CharField(max_length=200, null=True)
first_name = models.CharField(max_length=200, null=True)
last_name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, unique=True)
phone = models.CharField(max_length=200, null=True)
platformLogo= models.ImageField(upload_to=upload_path, default='logo.png', null=True, blank=False)
这是我的 forms.py
from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Customer
from django import forms
class CustomerForm(ModelForm):
class Meta:
model = Customer
fields = '__all__'
exclude = ['user', 'email','name','otp_code']
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','first_name','last_name', 'email', 'password1', 'password2']
这是我的意见.py
def loginUser(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = authenticate(username=username, password=password)
if user is not None:
user = User.objects.get(username=username)
otp= random.randrange(100000,999999)
user.customer.otp_code = otp
user.customer.save()
request.session['username'] = username
body = f"Dear {username}, your OTP for login is {otp}. Use this OTP to validate your login."
send_mail('OTP request',body,'email@gmail.com',[username], fail_silently=False)
messages.success(request, "Your OTP has been send to your email.")
return redirect("/otp_verification")
else:
messages.error(request, "Wrong Credentials!!")
return render(request,'login.html')
except:
messages.error(request, "Please enter email and password for login!")
return render(request,'login.html')
context={}
return render(request, "login.html", context)
def otp_verification(request):
username = request.session['username']
if request.method == "POST":
otp = request.POST.get('username')
user = User.objects.filter(username = username).first()
if otp == user.customer.otp_code:
messages.success(request, "OTP Success. Please login with your credentials!")
login(request, user)
messages.success(request, f' Wecome {username}')
return redirect("/")
else:
messages.error(request, "Wrong OTP!!")
return render(request, "otpVerification.html")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.