How to Use Django Phone Verify?¶
Installation¶
pip install django-phone-verify
Configuration¶
Add app to
INSTALLED_APPS
:
# In settings.py:
INSTALLED_APPS = [
...
'phone_verify',
]
Add settings in your
settings.py
file:
# Settings for phone_verify
PHONE_VERIFICATION = {
'BACKEND': 'phone_verify.backends.twilio.TwilioBackend',
'OPTIONS': {
'SID': 'fake',
'SECRET': 'fake',
'FROM': '+14755292729',
'SANDBOX_TOKEN':'123456',
},
'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 only
'VERIFY_SECURITY_CODE_ONLY_ONCE': False, # If False, then a security code can be used multiple times for verification
}
Migrate the database:
python manage.py migrate
This would create SMSVerification
table, which is used to store phone_number
, session_token
and security_code
.
Usage¶
NOTE: django-phone-verify
provides few APIs which can be added to your list of API endpoints. Its functionality can be extended further based on your use-case as explained below.
Case 1: Verify phone number before/after user registration¶
This case is suitable if you simply want to access the endpoints to register and verify a phone number (before or after the user registration).
To access the endpoints available in api_endpoints.rst, you just need to update your API’s URLs.
Add a default router:
# In urls.py
from rest_framework.routers import DefaultRouter
from phone_verify.api import VerificationViewSet
default_router = DefaultRouter(trailing_slash=False)
default_router.register('phone', VerificationViewSet, basename='phone')
urlpatterns = default_router.urls
NOTE: It is recommended that you should verify the phone number of users before their registration.
Case 2: Verify phone number at the time of user registration¶
This is the case when you choose to integrate your user registration process with phone number verification.
NOTE: Here, you’ll first register a phone number using /api/phone/register
and then, will use the endpoint /api/phone/verify_and_register
to create a user on successful verification of the phone number.
Add a default router in urls to redirect on one of your custom viewset:
# In urls.py
from rest_framework.routers import DefaultRouter
from yourapp.api import YourCustomViewSet
default_router = DefaultRouter(trailing_slash=False)
default_router.register('phone', YourCustomViewSet, basename='phone')
urlpatterns = default_router.urls
Create YourCustomSerializer:
# In serializers.py
from rest_framework import serializers
from phone_verify.serializers import SMSVerificationSerializer
class YourUserSerializer(serializers.Serializer):
username = serializers.CharField(required=True)
email = serializers.EmailField(required=True)
password = serializers.CharField(required=True)
first_name = serializers.CharField(default="First")
...
class YourCustomSerializer(UserSerializer, SMSVerificationSerializer):
...
Add a service to create users:
# In your services.py
from django.contrib.auth import get_user_model
def create_user_account(username, email, password, **extra_args):
user = get_user_model().objects.create_user(
username=username, email=email, password=password, **extra_args
)
...
return user
Create YourCustomViewSet:
# In your api.py
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from phone_verify.api import VerificationViewSet
from phone_verify import serializers as phone_serializers
from . import services, serializers
class YourCustomViewSet(VerificationViewSet):
@action(detail=False, methods=['POST'], permission_classes=[AllowAny], serializer_class=serializers.YourCustomSerializer)
def verify_and_register(self, request):
"""Function to verify phone number and register a user
Most of the code here is corresponding to the "verify" view already present in the package.
"""
serializer = phone_serializers.SMSVerificationSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
# Add your custom code here.
# An example is shown below:
serializer = serializers.YourUserSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = services.create_user_account(**serializer.validated_data)
return Response(serializer.data)
NOTE:
Using the above method, we are coupling the phone verification and user registration process. One can also override the
verify
view to perform additional actions such as registering the user, registering a company with the verified phone number, etc.After inheriting
VerificationViewSet
, in case you would like to overrideget_serializer_class
, then after specifying all your conditions, you must returnself.serializer_class
. For example:
def get_serializer_class(self):
if self.action == 'verify_and_register':
return serializers.YourCustomSerializer
...
else:
return self.serializer_class
Otherwise, serializer classes for verify
and register
views will not be available.
Latest
security_code
generated for aphone_number
can be found at/admin/phone_verify/smsverification/
URL.Django’s
post_save
signal can be leveraged through its usage inphone_verify.models.SMSVerification
function. Additional functionality can be hooked via thepost_save
signal by creating the following receiver.
# In signals.py
from phone_verify.models import SMSVerification
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.mail import send_mail
# `send_phone_verify_email` function will get fired when a new entry is created or the model instance is updated
@receiver(post_save, sender=SMSVerification)
def send_phone_verify_email(sender, instance=None, created=None, **kwargs):
# Check if the instance is created or not
if created:
send_mail(
subject='Subject here',
message='Here is the message.',
from_email='from@example.com',
recipient_list=['to@example.com'],
fail_silently=False,
)