Вход в Django с использованием Captcha и двухфакторной аутентификации
Я новичок в Django, и мне удалось создать свою собственную страницу входа, интегрированную с осями и репатчей, которая в основном отображает капчу после 3 неудачных попыток входа в систему с моими собственными сообщениями об ошибках - все это работает нормально, как требуется, но теперь я также хотел бы добавить двухфакторная аутентификация с тем, что я уже реализовал.
Мне удалось установить двухфакторный пакет аутентификации django, но, похоже, я вынужден использовать страницу входа в систему, которая поставляется с двухфакторным пакетом аутентификации. Я потратил так много времени на собственный логин и добавленные функции, мне отчаянно нужно сохранить это на месте. Я считаю, что могу редактировать файлы шаблона двухфакторной аутентификации, но основная проблема заключается в возможности использовать функции из моих существующих представлений / декораторов с двухфакторными представлениями аутентификации.
Ниже приведены мои текущие настройки:
URL-адреса
from django.urls import path, include
from . import views
urlpatterns = [
path('login/', views.loginpage, name="login"),
path('logout/', views.logoutuser, name="logout"),
...,
]
Вид
@axes_dispatch
@check_recaptcha_login
def loginpage(request, credentials: dict = None):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
#print(attempt_count)
attempt_count = attempt_count
context = {'attempt_count': attempt_count}
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active and attempt_count < 3:
login(request, user)
return redirect('home')
elif user.is_active and request.recaptcha_is_valid:
login(request, user)
return redirect('home')
if not user.is_active:
messages.error(request, 'Account for this User has not been Activated.')
else:
messages.error(request, 'Username or Password is Incorrect.')
#print(context)
return render(request, 'login.html', context)
Декоратор (для Captcha)
from django.conf import settings
from django.contrib import messages
from django.db.models import Sum
from functools import wraps
from axes.attempts import (
get_user_attempts,
)
import requests
def check_recaptcha_login(view_func, credentials: dict = None):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
attempts_list = get_user_attempts(request, credentials)
attempt_count = max(
(
attempts.aggregate(Sum("failures_since_start"))[
"failures_since_start__sum"
]
or 0
)
for attempts in attempts_list
)
print(attempt_count)
attempt_count = attempt_count
request.recaptcha_is_valid = None
if request.method == 'POST':
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.RECAPTCHA_PRIVATE_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
request.recaptcha_is_valid = True
else:
request.recaptcha_is_valid = False
if attempt_count > 2:
messages.error(request, 'Invalid reCAPTCHA. Please try again.')
return view_func(request, *args, **kwargs)
return _wrapped_view
Шаблон
{% extends 'base.html' %}
{% block title %}
{% if request.path == adminpage %}
Admin Login
{% else %}
User Login
{% endif %}
{% endblock %}
{#{% block title %}User Login{% endblock %}#}
{% block content %}
<div class="d-flex justify-content-center">
{% if request.path == adminpage %}
<h3 id="form-title">Admin Login</h3>
{% else %}
<h3 id="form-title">User Login</h3>
{% endif %}
</div>
<div class="d-flex justify-content-center form_container">
<form method="POST" action="">
{% csrf_token %}
<div align="center">
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="username" placeholder="Email" class="form-control">
</div>
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="password" placeholder="Password" class="form-control">
</div>
</div>
{% if attempt_count > 1 %}
{% include 'recaptcha.html' %}
{% endif %}
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Login">
</div>
</form>
</div>
{% include 'messages.html' %}
<div class="input-group mb-1">
</div>
<div class="mt-1">
{% if request.path == adminpage %}
{% else %}
<div class="d-flex justify-content-center links">
Don't have an account? <a href="{% url 'register' %}" class="ml-2">Sign Up</a>
</div>
{% endif %}
<div class="d-flex justify-content-center links">
Forgot Password? <a href="{% url 'request-password' %}" class="ml-2">Reset Password</a>
</div>
</div>
{% endblock content %}
У меня также есть эта настройка для моей страницы администратора с добавленной проверкой для is_staff (разрешено использовать Admin) - я не включил, поскольку он почти такой же, как указано выше, и должен иметь возможность адаптироваться, как только я узнаю, как реализовать вышеизложенное . Я был бы очень признателен, если бы кто-нибудь мог подсказать мне, как использовать функции моей страницы входа, упомянутые выше, с двухфакторным пакетом аутентификации, поскольку я в настоящее время потерялся. Спасибо