Переопределение LoginView с Django -OTP - PullRequest
0 голосов
/ 14 марта 2020

Я хочу использовать пакет django -otp для добавления двухфакторной аутентификации в мои логины. Тем не менее, их LoginView имеют 2 формы. 1 с анонимными пользователями, который показывает поле ввода токена otp с именем пользователя и паролем. Другой вариант для аутентифицированных пользователей, который показывает только поле ввода токена otp.

Однако проблема в том, что, даже если у пользователя нет настроенного устройства двухфакторной аутентификации, он показывает поле ввода токена для OTPAuthenticationForm и это сбивает с толку пользователей, которые ничего не настраивали. Таким образом, вам не нужно заполнять это поле, и вы все равно можете войти, но это все еще сбивает с толку пользователя, я верю.

это его LoginView:

class LoginView(auth_views.LoginView):
    otp_authentication_form = OTPAuthenticationForm
    otp_token_form = OTPTokenForm

    @cached_property
    def authentication_form(self):
        user = self.request.user
        if user.is_anonymous or user.is_verified():
            form = self.otp_authentication_form
        else:
            form = partial(self.otp_token_form, user)

        return form

    def form_valid(self, form):
        # OTPTokenForm does not call authenticate(), so we may need to populate
        # user.backend ourselves to keep login() happy.
        user = form.get_user()
        if not hasattr(user, 'backend'):
            user.backend = self.request.session[BACKEND_SESSION_KEY]

        return super().form_valid(form)

Однако, то, что я хочу сделать, это сначала показать встроенную AuthenticationForm Django для проверки подлинности, если пользователь прошел проверку подлинности, то показать OTPTokenForm, для которого требуется заполнение только двухфакторного токена аутентификации. Потому что до этого времени вы не знаете, включен ли пользователь 2fa или нет.

Итак, мой код ниже.

class SignInView(LoginView):
    template_name = 'accounts/login.html'
    form_class = AuthenticationForm
    otp_authentication_form = OTPAuthenticationForm
    otp_token_form = OTPTokenForm

    @cached_property
    def authentication_form(self):
        user = self.request.user
        form = AuthenticationForm
        if user.is_authenticated and not user.is_verified():
            form = partial(self.otp_token_form, user)
        return form

    @check_recaptcha
    def form_valid(self, form):
        user = form.get_user()

        if not hasattr(user, 'backend'):
            user.backend = self.request.session[BACKEND_SESSION_KEY]

        if user.is_authenticated and not self.request.user.is_verified():
             form = partial(self.otp_token_form, user)
             return self.render_to_response(self.get_context_data(form=form))

        messages.add_message(self.request, messages.SUCCESS, 'Successfully logged in!')
            return super().form_valid(form)

, что происходит сейчас, когда пользователь заполняет имя пользователя и пароль Затем я показываю жетон заполнения формы. однако, после заполнения, он возвращается к AuthenticationForm и веб-интерфейс жалуется, что имя пользователя и пароль не были заполнены. Похоже, я не могу передать аутентифицированного пользователя во 2-ю форму, которая происходит ниже:

form = partial(self.otp_token_form, user)
return self.render_to_response(self.get_context_data(form=form))

Посмотрев на все это, каково ваше предложение в коде изменения? или, может быть, другая идея для реализации этого.

...