diff --git a/biscuit/core/settings.py b/biscuit/core/settings.py
index 55dfa5a30c4041e7567b16d6229dfba91f60ed1e..78c56b8f3d80a51779edbcf5121119d9fffaadb2 100644
--- a/biscuit/core/settings.py
+++ b/biscuit/core/settings.py
@@ -66,8 +66,12 @@ INSTALLED_APPS = [
     'contact_form',
     'django_select2',
     'hattori',
+    'django_otp.plugins.otp_totp',
+    'django_otp.plugins.otp_static',
+    'django_otp',
     'biscuit.core',
     'impersonate',
+    'two_factor'
 ]
 
 INSTALLED_APPS += get_app_packages()
@@ -96,6 +100,7 @@ MIDDLEWARE = [
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django_otp.middleware.OTPMiddleware',
     'impersonate.middleware.ImpersonateMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
@@ -317,26 +322,21 @@ CRON_CLASSES = [
 
 ANONYMIZE_ENABLED = _settings.get('maintenance.anonymisable', True)
 
-if _settings.get('2fa.enabled', False):
-    for app in ['two_factor', 'django_otp.plugins.otp_totp', 'django_otp.plugins.otp_static', 'django_otp']:
-        INSTALLED_APPS.insert(INSTALLED_APPS.index('biscuit.core')+1, app)
-    MIDDLEWARE.insert(MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware')+1, 'django_otp.middleware.OTPMiddleware')
+LOGIN_URL = 'two_factor:login'
 
-    LOGIN_URL = 'two_factor:login'
+if _settings.get('2fa.yubikey.enabled', False):
+    INSTALLED_APPS.insert(INSTALLED_APPS.index('two_factor')+1, 'otp_yubikey')
 
-    if _settings.get('2fa.yubikey.enabled', False):
-        INSTALLED_APPS.insert(INSTALLED_APPS.index('two_factor')+1, 'otp_yubikey')
+if _settings.get('2fa.call.enabled', False):
+    TWO_FACTOR_CALL_GATEWAY = 'two_factor.gateways.twilio.gateway.Twilio'
 
-    if _settings.get('2fa.call.enabled', False):
-        TWO_FACTOR_CALL_GATEWAY = 'two_factor.gateways.twilio.gateway.Twilio'
+if _settings.get('2fa.sms.enabled', False):
+    TWO_FACTOR_SMS_GATEWAY = 'two_factor.gateways.twilio.gateway.Twilio'
 
-    if _settings.get('2fa.sms.enabled', False):
-        TWO_FACTOR_SMS_GATEWAY = 'two_factor.gateways.twilio.gateway.Twilio'
-
-    if _settings.get('2fa.twilio.sid', None):
-        MIDDLEWARE.insert(MIDDLEWARE.index('django_otp.middleware.OTPMiddleware')+1, 'two_factor.middleware.threadlocals.ThreadLocals')
-        TWILIO_SID = _settings.get('2fa.twilio.sid')
-        TWILIO_TOKEN = _settings.get('2fa.twilio.token')
-        TWILIO_CALLER_ID = _settings.get('2fa.twilio.callerid')
+if _settings.get('2fa.twilio.sid', None):
+    MIDDLEWARE.insert(MIDDLEWARE.index('django_otp.middleware.OTPMiddleware')+1, 'two_factor.middleware.threadlocals.ThreadLocals')
+    TWILIO_SID = _settings.get('2fa.twilio.sid')
+    TWILIO_TOKEN = _settings.get('2fa.twilio.token')
+    TWILIO_CALLER_ID = _settings.get('2fa.twilio.callerid')
 
 _settings.populate_obj(sys.modules[__name__])
diff --git a/biscuit/core/urls.py b/biscuit/core/urls.py
index 62bd0792cc3d72f4ae911e96e87902d409097bca..414aa9b24aa78acf2f9f8e4114a65a6b8eeda585 100644
--- a/biscuit/core/urls.py
+++ b/biscuit/core/urls.py
@@ -1,9 +1,11 @@
 from django.apps import apps
 from django.conf import settings
 from django.conf.urls.static import static
+from django.contrib.auth import views as auth_views
 from django.urls import include, path
 
 import debug_toolbar
+from two_factor.urls import urlpatterns as tf_urls
 
 from . import views
 
@@ -13,7 +15,8 @@ urlpatterns = [
     path('school_management', views.school_management, name='school_management'),
     path('school/information/edit', views.edit_school, name='edit_school_information'),
     path('school/term/edit', views.edit_schoolterm, name='edit_school_term'),
-    path('accounts/', include('django.contrib.auth.urls')),
+    path('', include(tf_urls)),
+    path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'),
     path('persons', views.persons, name='persons'),
     path('persons/accounts', views.persons_accounts, name='persons_accounts'),
     path('person', views.person, name='person'),
@@ -36,9 +39,6 @@ urlpatterns = [
 ]
 
 # Add URLs for optional features
-if 'two_factor' in settings.INSTALLED_APPS:
-    from two_factor.urls import urlpatterns as tf_urls  # noqa
-    urlpatterns += [path('', include(tf_urls))]
 if hasattr(settings, 'TWILIO_ACCOUNT_SID'):
     from two_factor.gateways.twilio.urls import urlpatterns as tf_twilio_urls  # noqa
     urlpatterns += [path('', include(tf_twilio_urls))]
diff --git a/pyproject.toml b/pyproject.toml
index cf6c461db9228320d492e5d46e516356181d086b..47cd5dd09ac965241c21d7e9eae0bc6414586757 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -50,15 +50,14 @@ django-hattori = "^0.2"
 psycopg2 = "^2.8"
 django_select2 = "^7.1"
 requests = "^2.22"
-django-two-factor-auth = { version = "^1.9", optional = true }
+django-two-factor-auth = "^1.9"
 django-otp-yubikey = { version = '^0.5.2', optional = true }
 twilio = { version = "^6.33", optional = true }
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]
-2fa = ["django-two-factor-auth"]
-twilio = ["twilio"]
-yubikey = ["django-otp-yubikey"]
+2fa-twilio = ["twilio"]
+2fa-yubikey = ["django-otp-yubikey"]
 
 [tool.poetry.dev-dependencies]
 sphinx = "^2.1"