One-Time Password (OTP) verification adds an extra layer of security to your web applications. In this tutorial, we’ll guide you through the process of creating an OTP verification form using AJAX and Django templates. This will allow users to receive an OTP via email or SMS and verify their identity before accessing certain features or data within your application.
Prerequisites
Before getting started, make sure you have the following installed:
- Python and Django: Ensure you have Python and Django set up on your development,., environment.
- Django
django-otp
package: Install it using pip:
pip install django-otp
- A working email setup in your Django project for sending OTPs.
Step 1: Create a Django App
Start by creating a Django app within your project:
python manage.py startapp otp_verification
Step 2: Model for Storing OTPs
In your app’s models.py
, define a model to store OTPs:
from django.db import models
from django.contrib.auth.models import User
class OTP(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
otp = models.CharField(max_length=6)
is_verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.otp
After defining the model, run migrations to create the database table:
python manage.py makemigrations
python manage.py migrate
Step 3: Create Django Views
In your app’s views.py
, create views for sending and verifying OTPs:
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.contrib.auth.models import User
import random
from .models import OTP
@login_required
def home(request):
return render(request, 'home.html')
@login_required
def send_otp(request):
if request.method == 'POST':
user = request.user
otp_code = ''.join(random.choice('0123456789') for _ in range(6))
OTP.objects.create(user=user, otp=otp_code)
# Send OTP via email
subject = 'Your OTP for Verification'
message = f'Your OTP is: {otp_code}'
from_email = 'your@email.com' # Replace with your email
recipient_list = [user.email]
send_mail(subject, message, from_email, recipient_list)
return JsonResponse({'message': 'OTP sent successfully'})
else:
return JsonResponse({'error': 'Invalid request method'})
@login_required
def verify_otp(request):
if request.method == 'POST':
user = request.user
otp_code = request.POST.get('otp')
otp_obj = OTP.objects.filter(user=user, otp=otp_code, is_verified=False).first()
if otp_obj:
otp_obj.is_verified = True
otp_obj.save()
return JsonResponse({'message': 'OTP verified successfully'})
else:
return JsonResponse({'error': 'Invalid OTP or OTP already verified'})
else:
return JsonResponse({'error': 'Invalid request method'})
Step 4: Create Template
Create templates for sending and verifying OTPs in your app’s templates
folder:
home.html
{% extends "base.html" %}
{% block content %}
<h2>OTP Verification</h2>
<form id="send-otp-form">
{% csrf_token %}
<button type="submit">Send OTP</button>
</form>
<div id="otp-response"></div>
<form id="verify-otp-form">
{% csrf_token %}
<label for="otp">Enter OTP:</label>
<input type="text" id="otp" name="otp" required>
<button type="submit">Verify OTP</button>
</form>
<div id="otp-verify-response"></div>
{% endblock %}
{% block scripts %}
<script>
// JavaScript to handle sending OTP via AJAX
document.getElementById('send-otp-form').addEventListener('submit', function (e) {
e.preventDefault();
fetch('{% url "send_otp" %}', {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value,
},
})
.then(response => response.json())
.then(data => {
document.getElementById('otp-response').innerText = data.message;
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred.');
});
});
// JavaScript to handle verifying OTP via AJAX
document.getElementById('verify-otp-form').addEventListener('submit', function (e) {
e.preventDefault();
const otp = document.getElementById('otp').value;
fetch('{% url "verify_otp" %}', {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `otp=${otp}`,
})
.then(response => response.json())
.then(data => {
document.getElementById('otp-verify-response').innerText = data.message;
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred.');
});
});
</script>
{% endblock %}
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Your Website Title{% endblock %}</title>
<!-- Add your CSS and JavaScript links here -->
</head>
<body>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<!-- Add more navigation links here -->
</ul>
</nav>
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>
{% else %}
<p><a href="{% url 'login' %}">Login</a> | <a href="{% url 'signup' %}">Sign up</a></p>
{% endif %}
</header>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<!-- Add your footer content here -->
</footer>
<!-- Add any scripts here if needed -->
</body>
</html>
Step 5: Update URLs
In your app’s urls.py
, define the URL s for the send and verify OTP views:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('send-otp/', views.send_otp, name='send_otp'),
path('verify-otp/', views.verify_otp, name='verify_otp'),
# Add other URLs as needed
]
Step 6: Update Base Template
In your project’s base template (base.html
), you can add a link to the “Send OTP” page for authenticated users:
{% if user.is_authenticated %}
<p><a href="{% url 'send_otp' %}">Send OTP</a></p>
{% endif %}
Step 7: Test the Application
Start your Django development server:
python manage.py runserver
Now, when authenticated users visit the “Send OTP” page, they can send an OTP via email. After receiving the OTP, they can visit the “Verify OTP” page to enter the code for verification. If successful, they will see a confirmation message.
You can customize the templates and styles to match your project’s design, and you may expand this functionality to include phone-based OTPs or integrate third-party OTP providers for additional security options..
Blogs You Might Like to Read!
- Folder and Directory Structure for Django Project: Best Practices
- Django Best Practices for Building Robust Web Applications
- How To Send Email in Django and DRF
- How to Create RBAC in Django with Multiple Users Types
- Django User Registration with Email Confirmation
- Login with OTP via Email/Phone in Django