Skip to main content

A Django app to support phone number verification using security code sent via SMS.

Project description

https://github.com/CuriousLearner/django-phone-verify/actions/workflows/main.yml/badge.svg?branch=master https://coveralls.io/repos/github/CuriousLearner/django-phone-verify/badge.svg?branch=master License https://static.pepy.tech/badge/django-phone-verify?period=total&units=international_system&left_color=black&right_color=darkgreen&left_text=Downloads https://img.shields.io/badge/Made%20with-Python-1f425f.svg https://img.shields.io/badge/Maintained%3F-yes-green.svg https://badge.fury.io/py/django-phone-verify.svg https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square

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://www.sanyamkhurana.com/django-phone-verify/

What It Does

django-phone-verify handles the complete phone verification flow:

  1. Send Verification Code - User requests verification, receives SMS with security code

  2. Verify Code - User submits code, system validates and confirms phone number

  3. Session Management - Secure JWT-based session tokens prevent tampering

  4. 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

  1. Add phone_verify to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "phone_verify",
    ...
]
  1. Run migrations:

python manage.py migrate
  1. Include the API URLs in your project’s urls.py:

from django.urls import path, include

urlpatterns = [
    ...
    path("api/phone/", include("phone_verify.urls")),
    ...
]
  1. 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_TIME": 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_TIME": 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://www.sanyamkhurana.com/django-phone-verify/

Quick Links:

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:

  1. 🐛 Report bugs via GitHub Issues

  2. 💡 Suggest features or improvements

  3. 🔧 Submit pull requests - please check the contributing guide first

  4. 📖 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_phone_verify-3.2.0.tar.gz (9.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_phone_verify-3.2.0-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file django_phone_verify-3.2.0.tar.gz.

File metadata

  • Download URL: django_phone_verify-3.2.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

Hashes for django_phone_verify-3.2.0.tar.gz
Algorithm Hash digest
SHA256 b70eaeb250ddf0a3686ca6815a6e6961b0c712e1b1cbd43300779094216324f7
MD5 4660e02cb2433089167b638c1cea291d
BLAKE2b-256 01ed8b11a0287e18c5cb11202561371bfbfff9ebe59a2de39268ac1628cc0ea1

See more details on using hashes here.

File details

Details for the file django_phone_verify-3.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_phone_verify-3.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0c5ae1484dcc56df4de761f092461b691850345f526903d3220535c53a579928
MD5 ccb2182b7a4616595cd1b897d988f0da
BLAKE2b-256 5c32f6ca3088f94b2ceb770dcea6a13c6905cd1183b42feab12298a546d31f15

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page