Django - Пользовательский вход с двухфакторной аутентификацией
После быстрого поиска и чтения документации я реализовал Django - двухфакторную аутентификацию в одном из моих проектов Django [Ссылка для справки].
Он отлично работает. Я использую Google Authenticator для входа на основе токенов. Проблема возникает, когда я хочу расширить методологию входа в библиотеку. Я хочу заставить каждого моего пользователя использовать двухфакторную аутентификацию в качестве принуждения. Я не использую никаких мер для регистрации, поэтому при входе в систему для пользователя должна быть произведена проверка .
Проблема заключается в разработке механизма пользовательского входа в систему, но я не могу включить эту библиотеку в пользовательский вход.
PS: У меня есть собственная модель пользователя, и в настоящее время я использую вход по умолчанию, который поставляется с двухфакторной аутентификацией Django.
Я не делал этого, хотя код был необходим, поэтому я не публиковал его, но при необходимости могу поделиться им.
3 ответа
После тщательного просмотра кода библиотеки я смог управлять проверкой в библиотеке two_factor.
Итак, глядя на
two_factor
Папка легко понять, что это не что иное, как приложение Django, похожее на другие.
Я перешел к файлам библиотеки в моей виртуальной среде
venv\Lib\site-packages\two_factor\views\core.py
. Как упоминалось в документации, до сих пор пользователи не принуждены к установке 2fa.
В
LoginView(...)
есть функция
done
. ИТ-специалисты проверяют доступность устройства для 2fa, просто добавьте предложение else для перенаправления.
def done(self, form_list, **kwargs):
"""
Login the user and redirect to the desired page.
"""
# Check if remember cookie should be set after login
current_step_data = self.storage.get_step_data(self.steps.current)
remember = bool(current_step_data and current_step_data.get('token-remember') == 'on')
login(self.request, self.get_user())
redirect_to = self.get_success_url()
device = getattr(self.get_user(), 'otp_device', None)
response = redirect(redirect_to)
if device:
signals.user_verified.send(sender=__name__, request=self.request,
user=self.get_user(), device=device)
# Set a remember cookie if activated
if getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_AGE', None) and remember:
# choose a unique cookie key to remember devices for multiple users in the same browser
cookie_key = REMEMBER_COOKIE_PREFIX + str(uuid4())
cookie_value = get_remember_device_cookie(user=self.get_user(),
otp_device_id=device.persistent_id)
response.set_cookie(cookie_key, cookie_value,
max_age=settings.TWO_FACTOR_REMEMBER_COOKIE_AGE,
domain=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_DOMAIN', None),
path=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_PATH', '/'),
secure=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SECURE', False),
httponly=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_HTTPONLY', True),
samesite=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SAMESITE', 'Lax'),
)
else:
return redirect('two_factor:setup')
return response
Итак, что происходит: проверка устройства может быть успешной только в том случае, если пользователь установил 2fa, но это никогда не будет правдой для непроверенного пользователя.
Я полностью понимаю, что будет более эффективный и элегантный метод для выполнения вышеуказанной задачи, но с моими небольшими знаниями и ограничениями по времени я должен это сделать. Я опубликую обновление, если я столкнусь с этим, и я также буду приветствовать отзывы о моем решении.
Вклад от «engineervix» был очень полезен, однако его можно просто обойти, пройдя одиночную аутентификацию и введя известный веб-адрес django. Однако это первый супершаг. В сочетании со стандартным base.html с проверкой request.user.is_verified мне кажется законченным решением. В качестве примера прикрепляю свой base.html.
Идея состоит в том, что все мои пользовательские веб-страницы создаются с расширением base.html. Если к base.html можно получить доступ только с помощью 2FA, то ко всем моим пользовательским веб-страницам можно получить доступ только с помощью 2FA. Добавлен специальный блок content_non_auth для управления учетными записями пользователей без 2FA.
django-two-factor-auth предоставляет
is_verified()
метод через django- otp
OTPMiddleware
. Согласно документам , этот метод
можно использовать для проверки того, был ли пользователь вошел в систему с использованием двухфакторной аутентификации.
У меня такой же сценарий, как у вас (пользовательская модель пользователя и механизм входа по умолчанию django-two-factor-auth ), поэтому я сделал следующее:
- установлен
LOGIN_REDIRECT_URL
на URL-адрес, для которого требуется проверенный пользователь. Назовем его, например,"dashboard"
- в представлении панели инструментов сделайте что-то вроде этого:
def dashboard_view(request):
if request.user.is_verified():
# user logged in using two-factor
return render(request, "dashboard/template.html")
else:
# user not logged in using two-factor
return redirect("two_factor:setup")