To implement a phone number verification system with Django REST Framework (DRF), you can follow the following steps. This system will allow users to provide their phone number, receive a verification code by SMS (for example via Twilio), and validate this code to verify their number.
Main Steps:
- Install necessary dependencies
- Edit user template to include phone number
- Create a template to store verification codes
- Configure an SMS sending service (e.g. Twilio)
- Create DRF serializers
- Create views and API routes
- Manage verification logic and security
1. Install Necessary Dependencies
First, make sure you have installed the necessary libraries:
- Django REST Framework: If you haven't already.
- Twilio: For sending SMS.
- django-phonenumber-field: For validating and formatting phone numbers.
Install them via pip:
pip install djangorestframework twilio django-phonenumber-field
Add phonenumber_field and rest_framework to your INSTALLED_APPS in settings.py:
# settings.py INSTALLED_APPS = [ # ... 'rest_framework', 'phonenumber_field', # ... ]
2. Change User Template to Include Phone Number
If you are using a custom user template, add a field for the phone number and a verification flag.
# models.py from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.db import models from phonenumber_field.modelfields import PhoneNumberField class UserManager(BaseUserManager): def create_user(self, email, username, phone_number, password=None): if not email: raise ValueError('Les utilisateurs doivent avoir une adresse email') if not phone_number: raise ValueError('Les utilisateurs doivent avoir un numéro de téléphone') user = self.model( email=self.normalize_email(email), username=username, phone_number=phone_number, ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, username, phone_number, password=None): user = self.create_user( email, username, phone_number, password=password, ) user.is_admin = True user.save(using=self._db) return user class CustomUser(AbstractBaseUser): email = models.EmailField(verbose_name='adresse email', max_length=255, unique=True) username = models.CharField(max_length=50, unique=True) phone_number = PhoneNumberField(unique=True, null=False, blank=False) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) is_phone_verified = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', 'phone_number'] def __str__(self): return self.email @property def is_staff(self): return self.is_admin
Note: If you already have a user model, be sure to add the phone_number and is_phone_verified fields appropriately.
3. Create a Template to Store Verification Codes
This template will store verification codes sent to users.
# models.py import random import string from django.utils import timezone from datetime import timedelta class PhoneVerification(models.Model): user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='phone_verifications') code = models.CharField(max_length=6) created_at = models.DateTimeField(auto_now_add=True) is_verified = models.BooleanField(default=False) def is_expired(self): return self.created_at <h3> 4. Configure an SMS Sending Service (Ex. Twilio) </h3> <p>You can use Twilio to send text messages. Start by creating a Twilio account and obtaining the necessary credentials (ACCOUNT_SID, AUTH_TOKEN, FROM_NUMBER).</p> <p>Add these configurations to your settings.py:<br> </p> <pre class="brush:php;toolbar:false"># settings.py TWILIO_ACCOUNT_SID = 'votre_account_sid' TWILIO_AUTH_TOKEN = 'votre_auth_token' TWILIO_FROM_NUMBER = '+1234567890' # Numéro Twilio
Create a utils.py file to manage sending SMS:
# utils.py from django.conf import settings from twilio.rest import Client def send_sms(to, message): client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN) message = client.messages.create( body=message, from_=settings.TWILIO_FROM_NUMBER, to=str(to) ) return message.sid
5. Create DRF Serializers
Create serializers to handle the verification request and code validation.
pip install djangorestframework twilio django-phonenumber-field
6. Create API Views and Routes
Create views to manage verification requests and code validation.
# settings.py INSTALLED_APPS = [ # ... 'rest_framework', 'phonenumber_field', # ... ]
Note: You may want to adjust these views as needed, such as if you want to create a user during verification or manage existing users differently.
7. Configure API Routes
Add the corresponding routes in your urls.py.
# models.py from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.db import models from phonenumber_field.modelfields import PhoneNumberField class UserManager(BaseUserManager): def create_user(self, email, username, phone_number, password=None): if not email: raise ValueError('Les utilisateurs doivent avoir une adresse email') if not phone_number: raise ValueError('Les utilisateurs doivent avoir un numéro de téléphone') user = self.model( email=self.normalize_email(email), username=username, phone_number=phone_number, ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, username, phone_number, password=None): user = self.create_user( email, username, phone_number, password=password, ) user.is_admin = True user.save(using=self._db) return user class CustomUser(AbstractBaseUser): email = models.EmailField(verbose_name='adresse email', max_length=255, unique=True) username = models.CharField(max_length=50, unique=True) phone_number = PhoneNumberField(unique=True, null=False, blank=False) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) is_phone_verified = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', 'phone_number'] def __str__(self): return self.email @property def is_staff(self): return self.is_admin
8. Add Additional Logics (Optional)
has. Generation of Unique Code per User
Edit the request view to associate the code with a specific user or create a new user.
b. Limit the Number of Requests
To avoid abuse, limit the number of verification requests per user or phone number.
# models.py import random import string from django.utils import timezone from datetime import timedelta class PhoneVerification(models.Model): user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='phone_verifications') code = models.CharField(max_length=6) created_at = models.DateTimeField(auto_now_add=True) is_verified = models.BooleanField(default=False) def is_expired(self): return self.created_at <h4> c. User Management during Verification </h4> <p>You can decide to create a user after verification or associate the number with an existing user.</p> <h3> 9. Tests and Validation </h3> <p>Be sure to test your system in a development environment before deploying it to production. Check that:</p>
- SMS messages are sent correctly.
- Codes are generated and stored securely.
- Checks expire after the set time.
- Errors are correctly handled and communicated to the user.
Complete Implementation Example
To give you an overview, here is a complete example of the affected files.
models.py
# settings.py TWILIO_ACCOUNT_SID = 'votre_account_sid' TWILIO_AUTH_TOKEN = 'votre_auth_token' TWILIO_FROM_NUMBER = '+1234567890' # Numéro Twilio
serializers.py
# utils.py from django.conf import settings from twilio.rest import Client def send_sms(to, message): client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN) message = client.messages.create( body=message, from_=settings.TWILIO_FROM_NUMBER, to=str(to) ) return message.sid
views.py
# serializers.py from rest_framework import serializers from .models import CustomUser, PhoneVerification from phonenumber_field.serializerfields import PhoneNumberField class PhoneVerificationRequestSerializer(serializers.Serializer): phone_number = PhoneNumberField() def validate_phone_number(self, value): if CustomUser.objects.filter(phone_number=value).exists(): raise serializers.ValidationError("Ce numéro de téléphone est déjà utilisé.") return value class PhoneVerificationCodeSerializer(serializers.Serializer): phone_number = PhoneNumberField() code = serializers.CharField(max_length=6) def validate(self, data): phone_number = data.get('phone_number') code = data.get('code') try: user = CustomUser.objects.get(phone_number=phone_number) except CustomUser.DoesNotExist: raise serializers.ValidationError("Utilisateur non trouvé avec ce numéro de téléphone.") try: verification = PhoneVerification.objects.filter(user=user, code=code, is_verified=False).latest('created_at') except PhoneVerification.DoesNotExist: raise serializers.ValidationError("Code de vérification invalide.") if verification.is_expired(): raise serializers.ValidationError("Le code de vérification a expiré.") data['user'] = user data['verification'] = verification return data
urls.py
# views.py from rest_framework import generics, status from rest_framework.response import Response from .serializers import PhoneVerificationRequestSerializer, PhoneVerificationCodeSerializer from .models import CustomUser, PhoneVerification from .utils import send_sms import random import string from django.utils import timezone from rest_framework.permissions import AllowAny class PhoneVerificationRequestView(generics.GenericAPIView): serializer_class = PhoneVerificationRequestSerializer permission_classes = [AllowAny] def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) phone_number = serializer.validated_data['phone_number'] # Générer un code de 6 chiffres code = ''.join(random.choices(string.digits, k=6)) try: user = CustomUser.objects.get(phone_number=phone_number) # Si l'utilisateur existe déjà, ne pas permettre la création d'un nouveau return Response({"detail": "Ce numéro de téléphone est déjà associé à un utilisateur."}, status=status.HTTP_400_BAD_REQUEST) except CustomUser.DoesNotExist: pass # Permettre la création si nécessaire # Créer une instance de PhoneVerification verification = PhoneVerification.objects.create(user=None, code=code) # user=None pour l'instant # Envoyer le code par SMS try: send_sms(phone_number, f"Votre code de vérification est : {code}") except Exception as e: return Response({"detail": "Erreur lors de l'envoi du SMS."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"detail": "Code de vérification envoyé."}, status=status.HTTP_200_OK) class PhoneVerificationCodeView(generics.GenericAPIView): serializer_class = PhoneVerificationCodeSerializer permission_classes = [AllowAny] def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] verification = serializer.validated_data['verification'] # Marquer la vérification comme validée verification.is_verified = True verification.save() # Mettre à jour l'utilisateur user.is_phone_verified = True user.save() return Response({"detail": "Numéro de téléphone vérifié avec succès."}, status=status.HTTP_200_OK)
utils.py
# urls.py from django.urls import path from .views import PhoneVerificationRequestView, PhoneVerificationCodeView urlpatterns = [ path('api/verify-phone/request/', PhoneVerificationRequestView.as_view(), name='phone-verification-request'), path('api/verify-phone/verify/', PhoneVerificationCodeView.as_view(), name='phone-verification-verify'), ]
10. Secure and Optimize
Limit Verification Attempts: Implement a system to limit the number of verification attempts to avoid brute force attacks.
Encrypt Codes: For added security, you can encrypt the verification codes in the database.
Use Asynchronous Tasks: To improve performance, use asynchronous tasks (for example with Celery) to send SMS without blocking API requests.
Configure HTTPS: Make sure your API is accessible via HTTPS to secure communications.
The above is the detailed content of Implementing phone number verification in a drf project. For more information, please follow other related articles on the PHP Chinese website!

Pythonlistscanstoreanydatatype,arraymodulearraysstoreonetype,andNumPyarraysarefornumericalcomputations.1)Listsareversatilebutlessmemory-efficient.2)Arraymodulearraysarememory-efficientforhomogeneousdata.3)NumPyarraysareoptimizedforperformanceinscient

WhenyouattempttostoreavalueofthewrongdatatypeinaPythonarray,you'llencounteraTypeError.Thisisduetothearraymodule'sstricttypeenforcement,whichrequiresallelementstobeofthesametypeasspecifiedbythetypecode.Forperformancereasons,arraysaremoreefficientthanl

Pythonlistsarepartofthestandardlibrary,whilearraysarenot.Listsarebuilt-in,versatile,andusedforstoringcollections,whereasarraysareprovidedbythearraymoduleandlesscommonlyusedduetolimitedfunctionality.

ThescriptisrunningwiththewrongPythonversionduetoincorrectdefaultinterpretersettings.Tofixthis:1)CheckthedefaultPythonversionusingpython--versionorpython3--version.2)Usevirtualenvironmentsbycreatingonewithpython3.9-mvenvmyenv,activatingit,andverifying

Pythonarrayssupportvariousoperations:1)Slicingextractssubsets,2)Appending/Extendingaddselements,3)Insertingplaceselementsatspecificpositions,4)Removingdeleteselements,5)Sorting/Reversingchangesorder,and6)Listcomprehensionscreatenewlistsbasedonexistin

NumPyarraysareessentialforapplicationsrequiringefficientnumericalcomputationsanddatamanipulation.Theyarecrucialindatascience,machinelearning,physics,engineering,andfinanceduetotheirabilitytohandlelarge-scaledataefficiently.Forexample,infinancialanaly

Useanarray.arrayoveralistinPythonwhendealingwithhomogeneousdata,performance-criticalcode,orinterfacingwithCcode.1)HomogeneousData:Arrayssavememorywithtypedelements.2)Performance-CriticalCode:Arraysofferbetterperformancefornumericaloperations.3)Interf

No,notalllistoperationsaresupportedbyarrays,andviceversa.1)Arraysdonotsupportdynamicoperationslikeappendorinsertwithoutresizing,whichimpactsperformance.2)Listsdonotguaranteeconstanttimecomplexityfordirectaccesslikearraysdo.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

WebStorm Mac version
Useful JavaScript development tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.
