A Django app to support phone number verification using security code sent via SMS.
Project description
A Django app to support phone number verification using a security code sent via SMS.
django-phone-verify provides a simple, secure way to verify phone numbers for user authentication, 2FA, account recovery, and more. It works seamlessly with Django and Django REST Framework, supports multiple SMS providers (Twilio, Nexmo/Vonage), and is fully extensible with custom backends.
📖 Full Documentation: https://django-phone-verify.readthedocs.io/
What It Does
django-phone-verify handles the complete phone verification flow:
Send Verification Code - User requests verification, receives SMS with security code
Verify Code - User submits code, system validates and confirms phone number
Session Management - Secure JWT-based session tokens prevent tampering
Multiple Use Cases - Registration, 2FA, password reset, marketing opt-in, and more
Key Features
Security & Flexibility
🔐 Secure verification flow - JWT session tokens, configurable code expiration, one-time use options
🔧 Highly customizable - Token length, expiration time, message templates, custom backends
🔒 Production-ready - Rate limiting support, security best practices, GDPR/CCPA compliance guidance
Easy Integration
🚀 Django REST Framework - Pre-built viewsets and serializers for instant API setup
🔌 Pluggable backends - Use Twilio, Nexmo/Vonage, or write your own (AWS SNS, MessageBird, etc.)
✅ Non-intrusive - Works with any AUTH_USER_MODEL, no database changes required to your user model
🧪 Sandbox mode - Test flows without sending real SMS messages
Multiple Use Cases
👤 User registration phone verification
🔑 Two-factor authentication (2FA)
🔄 Account recovery / password reset
📧 Marketing opt-in verification
📱 Phone number update flows
Installation
Install the package with all supported backends:
pip install django-phone-verify[all]
Or install with just the backend you need:
pip install django-phone-verify[twilio]
pip install django-phone-verify[nexmo]
Configuration
Add phone_verify to INSTALLED_APPS:
INSTALLED_APPS = [
...
"phone_verify",
...
]
Run migrations:
python manage.py migrate
Include the API URLs in your project’s urls.py:
from django.urls import path, include
urlpatterns = [
...
path("api/phone/", include("phone_verify.urls")),
...
]
Configure PHONE_VERIFICATION settings in your settings.py:
For Twilio:
PHONE_VERIFICATION = {
"BACKEND": "phone_verify.backends.twilio.TwilioBackend",
"OPTIONS": {
"SID": "your-twilio-account-sid",
"SECRET": "your-twilio-auth-token",
"FROM": "+1234567890", # Your Twilio phone number
"SANDBOX_TOKEN": "123456", # Optional: for testing without sending real SMS
},
"TOKEN_LENGTH": 6,
"MESSAGE": "Welcome to {app}! Please use security code {security_code} to proceed.",
"APP_NAME": "Phone Verify",
"SECURITY_CODE_EXPIRATION_SECONDS": 3600, # in seconds
"VERIFY_SECURITY_CODE_ONLY_ONCE": False,
}
For Nexmo (Vonage):
PHONE_VERIFICATION = {
"BACKEND": "phone_verify.backends.nexmo.NexmoBackend",
"OPTIONS": {
"KEY": "your-nexmo-api-key",
"SECRET": "your-nexmo-api-secret",
"FROM": "YourApp", # Sender ID
"SANDBOX_TOKEN": "123456", # Optional: for testing
},
"TOKEN_LENGTH": 6,
"MESSAGE": "Welcome to {app}! Please use security code {security_code} to proceed.",
"APP_NAME": "Phone Verify",
"SECURITY_CODE_EXPIRATION_SECONDS": 3600,
"VERIFY_SECURITY_CODE_ONLY_ONCE": False,
}
Quick Start
Step 1: Send verification code
curl -X POST http://localhost:8000/api/phone/register/ \
-H "Content-Type: application/json" \
-d '{"phone_number": "+1234567890"}'
# Response:
# {
# "session_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
# "phone_number": "+1234567890"
# }
Step 2: Verify the code
curl -X POST http://localhost:8000/api/phone/verify/ \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+1234567890",
"security_code": "123456",
"session_token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}'
# Response:
# {
# "message": "Security code is valid",
# "phone_number": "+1234567890"
# }
Using in Python/Django code:
from phone_verify.services import send_security_code_and_generate_session_token
from phone_verify.services import verify_security_code
# Send verification code via SMS
session_token = send_security_code_and_generate_session_token(
phone_number="+1234567890"
)
# User receives SMS: "Welcome to Phone Verify! Please use security code 847291 to proceed."
# Verify the code user entered
try:
verify_security_code(
phone_number="+1234567890",
security_code="847291",
session_token=session_token
)
print("✓ Phone number verified successfully!")
except Exception as e:
print(f"✗ Verification failed: {e}")
Documentation
Full documentation is available at https://django-phone-verify.readthedocs.io/
Quick Links:
🚀 Advanced Examples (2FA, password reset, marketing opt-in)
Compatibility
Python 3.8+ (Python 3.7 and below are EOL)
Django 2.1+
Django REST Framework 3.9+
Contributing
Found a bug? Want to suggest an improvement or submit a patch?
We welcome contributions! Here’s how you can help:
🐛 Report bugs via GitHub Issues
💡 Suggest features or improvements
🔧 Submit pull requests - please check the contributing guide first
📖 Improve documentation
Before submitting a PR:
Write tests for new features
Ensure all tests pass: pytest
Follow the existing code style
Update documentation if needed
License
This project is licensed under the GPLv3 license.
Changelog
See the full changelog here: 📄 CHANGELOG.rst
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_phone_verify-3.3.0.tar.gz.
File metadata
- Download URL: django_phone_verify-3.3.0.tar.gz
- Upload date:
- Size: 9.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb6e8df5fba8141b6674f1c7a18cd31faa622299218ecd5e2162d407a35bab8b
|
|
| MD5 |
77fc60e84fd0b492a2c1d9d61cd3c843
|
|
| BLAKE2b-256 |
d1980dc1067e43ee12cc5067bfa3d8c09bbf2908c83d5b1e2ca01f149f5ce968
|
File details
Details for the file django_phone_verify-3.3.0-py3-none-any.whl.
File metadata
- Download URL: django_phone_verify-3.3.0-py3-none-any.whl
- Upload date:
- Size: 34.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae5f46572e961961fde06271eb4a8aeecac265e292983eec092c00edea64fe64
|
|
| MD5 |
285d2bead5b723ffb50fa1dc2510fddc
|
|
| BLAKE2b-256 |
b7aa91af5167aac01949068750e8932ec6f05fb57d42362c35ac4849e46ee19d
|