Я пытался реализовать django-otp с qrcode с использованием пользовательских форм и представлений.Проблема в том, что я немного увлечен тем, правильна ли моя реализация или нет.Поскольку в документации говорится, что атрибут request.user.is_verified()
добавляется пользователям, прошедшим проверку OTP, я на самом деле не могу сделать это правильно.Создано подтвержденное устройство TOTP для пользователя с настройкой QR-кода с помощью приложения Microsoft Authenticator.
Я смог успешно выполнить проверку OTP Admin Site по умолчанию без каких-либо проблем.Ниже приведены файлы для пользовательской реализации.
urls.py
from django.conf.urls import url
from account.views import AccountLoginView, AccountHomeView, AccountLogoutView
urlpatterns = [
url(r'^login/$', AccountLoginView.as_view(), name='account-login',),
url(r'^home/$', AccountHomeView.as_view(), name='account-home',),
url(r'^logout/$', AccountLogoutView.as_view(), name='account-logout',)
]
views.py
from django.contrib.auth import authenticate, login as auth_login
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django_otp.forms import OTPAuthenticationForm
class AccountLoginView(FormView):
template_name = 'login.html'
form_class = OTPAuthenticationForm
success_url = '/account/home/'
def form_invalid(self, form):
return super().form_invalid(form)
def form_valid(self, form):
# self.request.user returns AnonymousUser
# self.request.user.is_authenticated returns False
# self.request.user.is_verified() returns False
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
otp_token = form.cleaned_data.get('otp_token')
otp_device = form.cleaned_data.get('otp_device')
user = authenticate(request=self.request, username=username, password=password)
if user is not None:
device_match = match_token(user=user, token=otp_token)
# device_match returns None
auth_login(self.request, user)
# self.request.user returns admin@mywebsite.com
# self.request.user.authenticated returns True
# self.request.user.is_verified returns AttributeError 'User' object has no attribute 'is_verified'
# user.is_verified returns AttributeError 'User' object has no attribute 'is_verified'
return super().form_valid(form)
class AccountHomeView(TemplateView):
template_name = 'account.html'
def get(self, request, *args, **kwargs):
# request.user.is_authenticated returns True
# request.user.is_verified() returns False
return super(AccountHomeView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['data'] = 'This is secured text'
return context
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="." method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.username.errors }}
<label for="{{ form.username.id_for_label }}">{{ form.username.label_tag }}</label>
{{ form.username }}
</div>
<div class="fieldWrapper">
{{ form.password.errors }}
<label for="{{ form.password.id_for_label }}">{{ form.password.label_tag }}</label>
{{ form.password }}
</div>
{% if form.get_user %}
<div class="fieldWrapper">
{{ form.otp_device.errors }}
<label for="{{ form.otp_device.id_for_label }}">{{ form.otp_device.label_tag }}</label>
{{ form.otp_device }}
</div>
{% endif %}
<div class="fieldWrapper">
{{ form.otp_token.errors }}
<label for="{{ form.otp_token.id_for_label }}">{{ form.otp_token.label_tag }}</label>
{{ form.otp_token }}
</div>
<input type="submit" value="Log In" />
{% if form.get_user %}
<input type="submit" name="otp_challenge" value="Get Challenge" />
{% endif %}
</form>
</body>
</html>
Может кто-нибудь, пожалуйста, дайте мне знать, что мне не хватает.Я хочу иметь возможность аутентифицировать и проверять их, используя мои собственные представления, используя существующие классы форм OTP.
Пожалуйста, совет.