djangodjango-two-factor-auth

no account logout Django Two factor auth


i am trying to implement two factor auth in my Django app. However, the user can bypass it by using the login provided by django.contrib.auth. is there any way i can redirect the user to /account/login when they browse for /login?

Things i tried and have not work:

redundant login urls

settings.py

from pathlib import Path
import os

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'main.apps.MainConfig',
    'booking.apps.BookingConfig',
    'formtools',
    'register.apps.RegisterConfig',
    "crispy_forms",
    'django_otp',
    'django_otp.plugins.otp_static',
    'django_otp.plugins.otp_totp',
    'django_otp.plugins.otp_email',  # <- if you want email capability.
    'two_factor',
    'two_factor.plugins.email',  # <- if you want email capability.

]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',

    "whitenoise.middleware.WhiteNoiseMiddleware",

    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_otp.middleware.OTPMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

LOGIN_URL = 'two_factor:login'

LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"

CSRF_TRUSTED_ORIGINS = ['some random header']
AUTH_USER_MODEL = 'register.User'

urls.py

from django.contrib import admin
from django.urls import path, include
from register import views as v
from django.contrib.auth.decorators import login_required
from two_factor.urls import urlpatterns as tf_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("main.urls")),
    path("register/",v.register, name="register"),
    path('booking/', include("booking.urls")),
    path('',include("django.contrib.auth.urls")),
    path('', include(tf_urls)),
]

Solution

  • Alright, i found another solution. Here's how i did it. This Django two factor auth lacks redirect URL. So instead of using two factor auth use 2fa. it works well with the build in django.contrib.auth. after logging in using the built in login, you can redirect the user to the 2fa login which is exactly what i wanted.

    settings.py

    LOGIN_URL = "/login"
    MFA_URL = '/2fa/login'
    MFA_REDIRECT_FIELD = 'next'
    MFA_PROTECT_PATH_STARTSWITH = None
    
    LOGIN_REDIRECT_URL = "/"
    LOGOUT_REDIRECT_URL = "/"
    
    SALT_KEY = "skfmrgfhtolstehsmgocbetshtpanrpshtnf" #this is just random 36 character
    

    urls.py

    urlpatterns = [
        ...extra paths,
        path('2fa/', include(django_2fa.urls)),
        path('',include("django.contrib.auth.urls")),
        
    ]