In today's digital landscape, ensuring the authenticity of user accounts is paramount for web applications. One effective method to achieve this is through email and mobile number verification using One-Time Passwords (OTPs). This article will guide you through the process of implementing OTP verification in a Django project, explaining its importance and providing actionable steps for implementation.
Table of Contents
- Introduction
- Why OTP Verification Matters
- Prerequisites
- Step-by-Step Implementation
- Best Practices and Considerations
- Conclusion
Introduction
One-Time Passwords (OTPs) are unique, temporary codes used to verify a user's identity. By implementing OTP verification for both email and mobile numbers, you add an extra layer of security to your application, ensuring that users have access to the contact methods they've provided.
Why OTP Verification Matters
- Enhanced Security: OTP verification significantly reduces the risk of unauthorized access and account takeovers.
- User Authentication: It confirms that users have provided valid contact information, which is crucial for account recovery and communication.
- Fraud Prevention: It helps prevent the creation of fake accounts, as users must prove ownership of their email and phone number.
- Compliance: Many regulatory standards require multi-factor authentication, which OTP verification can help satisfy.
- User Trust: Implementing strong security measures like OTP verification builds user confidence in your application.
Prerequisites
Before we begin, make sure you have the following:
- Python 3.x installed
- Basic knowledge of Django
- A Django project set up (if not, we'll cover that in the steps)
Step-by-Step Implementation
Let's dive into the process of implementing OTP verification in a Django project.
Step 1: Set up the Django project and app
First, let's create a new Django project and app:
django-admin startproject otp_verification
cd otp_verification
python manage.py startapp user_auth
Add 'user_auth' to INSTALLED_APPS in your project's settings.py file:
INSTALLED_APPS = [
...
'user_auth',
]
Step 2: Install required packages
We'll need a couple of additional packages:
pip install django-otp pyotp
Step 3: Create the User model
In your user_auth/models.py
file, create a custom user model:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
mobile_number = models.CharField(max_length=15, unique=True)
is_email_verified = models.BooleanField(default=False)
is_mobile_verified = models.BooleanField(default=False)
email_otp = models.CharField(max_length=6, null=True, blank=True)
mobile_otp = models.CharField(max_length=6, null=True, blank=True)
Step 4: Create OTP generation and verification functions
Create a new file user_auth/utils.py
:
import pyotp
from datetime import datetime, timedelta
def generate_otp():
totp = pyotp.TOTP(pyotp.random_base32(), interval=300) # 5 minutes validity
return totp.now()
def verify_otp(otp, user_otp):
return otp == user_otp
Step 5: Create views for registration and OTP verification
In your user_auth/views.py
file:
from django.shortcuts import render, redirect
from django.contrib.auth import login
from .models import CustomUser
from .utils import generate_otp, verify_otp
from django.core.mail import send_mail
from django.conf import settings
def register(request):
if request.method == 'POST':
username = request.POST['username']
email = request.POST['email']
mobile_number = request.POST['mobile_number']
password = request.POST['password']
user = CustomUser.objects.create_user(username=username, email=email,
mobile_number=mobile_number, password=password)
# Generate and save OTPs
email_otp = generate_otp()
mobile_otp = generate_otp()
user.email_otp = email_otp
user.mobile_otp = mobile_otp
user.save()
# Send email OTP
send_mail(
'Email Verification OTP',
f'Your OTP for email verification is: {email_otp}',
settings.EMAIL_HOST_USER,
[email],
fail_silently=False,
)
# Send mobile OTP (you'll need to integrate with an SMS service)
# For this example, we'll just print it
print(f"Mobile OTP: {mobile_otp}")
return redirect('verify_otp', user_id=user.id)
return render(request, 'register.html')
def verify_otp(request, user_id):
user = CustomUser.objects.get(id=user_id)
if request.method == 'POST':
email_otp = request.POST['email_otp']
mobile_otp = request.POST['mobile_otp']
if verify_otp(email_otp, user.email_otp) and verify_otp(mobile_otp, user.mobile_otp):
user.is_email_verified = True
user.is_mobile_verified = True
user.email_otp = None
user.mobile_otp = None
user.save()
login(request, user)
return redirect('home')
else:
return render(request, 'verify_otp.html', {'error': 'Invalid OTP'})
return render(request, 'verify_otp.html')
Step 6: Create URL patterns
In your user_auth/urls.py
file:
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.register, name='register'),
path('verify_otp/<int:user_id>/', views.verify_otp, name='verify_otp'),
]
Don't forget to include these URLs in your project's main urls.py
file.
Step 7: Create templates
Create two HTML templates in your templates
directory:
register.html
:
<form method="post">
{% csrf_token %}
<input type="text" name="username" placeholder="Username" required>
<input type="email" name="email" placeholder="Email" required>
<input type="text" name="mobile_number" placeholder="Mobile Number" required>
<input type="password" name="password" placeholder="Password" required>
<button type="submit">Register</button>
</form>
verify_otp.html
:
<form method="post">
{% csrf_token %}
<input type="text" name="email_otp" placeholder="Email OTP" required>
<input type="text" name="mobile_otp" placeholder="Mobile OTP" required>
<button type="submit">Verify OTP</button>
</form>
Step 8: Configure email settings
In your project's settings.py
file, add the following email configuration:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com' # Use your email provider's SMTP server
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your_email@gmail.com'
EMAIL_HOST_PASSWORD = 'your_email_password'
Replace the placeholder values with your actual email credentials.
Step 9: Run migrations
Apply the database migrations:
python manage.py makemigrations
python manage.py migrate
Step 10: Run the server
Start the Django development server:
python manage.py runserver
Best Practices and Considerations
- Security: In a production environment, use more secure methods for storing OTPs, such as hashing them before saving to the database.
- SMS Integration: Integrate with a reliable SMS service provider to send mobile OTPs.
- OTP Expiry: Implement a mechanism to expire OTPs after a certain time period.
- Rate Limiting: Implement rate limiting to prevent abuse of the OTP generation and verification endpoints.
- Error Handling: Add robust error handling and user feedback for a smoother user experience.
- Resend OTP: Provide an option for users to request a new OTP if they don't receive the first one.
- Progressive Enhancement: Allow users to access limited functionality even if they haven't verified their contact methods, but require verification for sensitive actions.
Conclusion
Implementing email and mobile OTP verification in your Django application significantly enhances security and user trust. By following this guide, you've learned how to set up a basic OTP verification system. Remember to adapt this implementation to your specific needs and always prioritize user data security.
As you continue to develop your application, consider integrating additional security measures and regularly updating your authentication methods to stay ahead of potential threats. With OTP verification in place, you're taking a crucial step towards building a more secure and trustworthy web application.
Connect with me on my social media platforms for more updates and insights:
- Twitter: @rupeshmisra2002
- LinkedIn: Rupesh Mishra
- GitHub: Rupesh Mishra
Top comments (0)