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://django-phone-verify.readthedocs.io/

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_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:

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.3.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.3.0-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

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

Hashes for django_phone_verify-3.3.0.tar.gz
Algorithm Hash digest
SHA256 fb6e8df5fba8141b6674f1c7a18cd31faa622299218ecd5e2162d407a35bab8b
MD5 77fc60e84fd0b492a2c1d9d61cd3c843
BLAKE2b-256 d1980dc1067e43ee12cc5067bfa3d8c09bbf2908c83d5b1e2ca01f149f5ce968

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_phone_verify-3.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ae5f46572e961961fde06271eb4a8aeecac265e292983eec092c00edea64fe64
MD5 285d2bead5b723ffb50fa1dc2510fddc
BLAKE2b-256 b7aa91af5167aac01949068750e8932ec6f05fb57d42362c35ac4849e46ee19d

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