【问题标题】:Is it possible to disable Django two-factor authentication with a setting?是否可以通过设置禁用 Django 双重身份验证?
【发布时间】:2018-10-11 23:31:19
【问题描述】:

我正在尝试为受Django Two-Factor Authentication 保护的网站编写LiveServerTestCase。到目前为止我所拥有的是:

import os
from urllib.parse import urljoin
from django.urls import reverse
from django.conf import settings
from lucy_web.test_factories import UserFactory

from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver

chromedriver_path = os.path.join(os.path.dirname(os.path.dirname(settings.BASE_DIR)), 'chromedriver')
assert os.path.isfile(chromedriver_path), f"There should be a chromedriver executable at {chromedriver_path}"


class SeleniumTest(StaticLiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.driver = webdriver.Chrome(chromedriver_path)
        cls.password = 'foobar'         # Set the password here to avoid using the hashed attribute
        cls.user = UserFactory(password=cls.password, is_superuser=True)

    def test_login(self):
        url = urljoin(self.live_server_url, reverse('dashboard:families'))
        self.driver.get(url)
        self.driver.find_element_by_name('auth-username').send_keys(self.user.username)
        self.driver.find_element_by_name('auth-password').send_keys(self.password)
        self.driver.find_element_by_xpath('//input[@value="Next"]').click()

问题是,此时,驱动程序到达一个需要扫描二维码的双重身份验证登录页面:

使用测试浏览器太复杂了,所以我想使用override_settings 禁用两因素身份验证以进行测试。但是,查看 Django 双重身份验证的General Settings,我找不到禁用它的设置。

有什么方法可以禁用双因素身份验证以继续此实时服务器测试用例?

【问题讨论】:

    标签: django selenium two-factor-authentication


    【解决方案1】:

    没有执行此操作的内置功能,但您可以通过扩展中间件轻松完成。只需将设置中的“OTPMiddleware”与此设置的完整虚线路径交换,然后根据需要将 DEBUG 更改为其他变量。

    from django_otp import DEVICE_ID_SESSION_KEY, _user_is_authenticated
    from django_otp.models import Device
    from django_otp.middleware import OTPMiddleware, is_verified
    from django.conf import settings
    class ToggleableOTPMiddleware(OTPMiddleware):
        def _verify_user(self, request, user):
            """
            Sets OTP-related fields on an authenticated user.
            """
            user.otp_device = None
    
            # START CHANGE
            if settings.DEBUG:
                user.is_verified = lambda: True
            else:
                user.is_verified = functools.partial(is_verified, user)
            # END CHANGE
    
            if _user_is_authenticated(user):
                persistent_id = request.session.get(DEVICE_ID_SESSION_KEY)
                device = self._device_from_persistent_id(persistent_id) if persistent_id else None
    
                if (device is not None) and (device.user_id != user.id):
                    device = None
    
                if (device is None) and (DEVICE_ID_SESSION_KEY in request.session):
                    del request.session[DEVICE_ID_SESSION_KEY]
    
                user.otp_device = device
    
            return user
    

    【讨论】:

    • 理想情况下,我不想更改代码库只是为了适应测试,因为这会引入新错误的可能性。在这个特定的例子中,是否有办法生成一个有效的令牌作为测试夹具?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    相关资源
    最近更新 更多