Skip to content

Instantly share code, notes, and snippets.

@jtiai
Created February 19, 2019 10:30
Show Gist options
  • Save jtiai/4243e7097edd01327f658281ce2984d6 to your computer and use it in GitHub Desktop.
Save jtiai/4243e7097edd01327f658281ce2984d6 to your computer and use it in GitHub Desktop.
Django simple OTP
from django import forms
from django.conf import settings
from django.contrib.auth.forms import AuthenticationForm
from django.core.mail import send_mail
class OTPAuthenticationForm(AuthenticationForm):
otp = forms.CharField(required=False, widget=forms.PasswordInput)
def clean(self):
# Allow Django to detect can user log in
super(OTPAuthenticationForm, self).clean()
# If we got this far, we know that user can log in.
if self.request.session.has_key('_otp'):
if self.request.session['_otp'] != self.cleaned_data['otp']:
raise forms.ValidationError("Invalid OTP.")
del self.request.session['_otp']
else:
# There is no OTP so create one and send it by email
otp = "1234"
send_mail(
subject="Your OTP Password",
message="Your OTP password is %s" % otp,
from_email=settings.EMAIL_HOST_USER,
recipient_list=[self.user_cache.email]
)
self.request.session['_otp'] = otp
# Now we trick form to be invalid
raise forms.ValidationError("Enter OTP you received via e-mail")
# This is my root urlconf
from django.contrib import admin
from django.urls import path, include
from otp import views
from otp import forms
from django.contrib.auth.views import LoginView
urlpatterns = [
path('admin/', admin.site.urls),
# Override default login to use our form
path('accounts/login/', LoginView.as_view(authentication_form=forms.OTPAuthenticationForm), name="login"),
path('accounts/', include('django.contrib.auth.urls')),
path('', views.index),
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment