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 ), поэтому я сделал следующее:

  1. установлен LOGIN_REDIRECT_URLна URL-адрес, для которого требуется проверенный пользователь. Назовем его, например, "dashboard"
  2. в представлении панели инструментов сделайте что-то вроде этого:
      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")
Другие вопросы по тегам