Um ein Telefonnummernüberprüfungssystem mit Django REST Framework (DRF) zu implementieren, können Sie die folgenden Schritte ausführen. Dieses System ermöglicht es Benutzern, ihre Telefonnummer anzugeben, einen Bestätigungscode per SMS zu erhalten (z. B. über Twilio) und diesen Code zu validieren, um ihre Nummer zu bestätigen.
Stellen Sie zunächst sicher, dass Sie die erforderlichen Bibliotheken installiert haben:
Installieren Sie sie über pip:
pip install djangorestframework twilio django-phonenumber-field
Fügen Sie phonenumber_field und rest_framework zu Ihren INSTALLED_APPS in Settings.py hinzu:
# settings.py INSTALLED_APPS = [ # ... 'rest_framework', 'phonenumber_field', # ... ]
Wenn Sie eine benutzerdefinierte Benutzervorlage verwenden, fügen Sie ein Feld für die Telefonnummer und ein Verifizierungskennzeichen hinzu.
# 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
Hinweis: Wenn Sie bereits über ein Benutzermodell verfügen, stellen Sie sicher, dass Sie die Felder „phone_number“ und „is_phone_verified“ entsprechend hinzufügen.
In dieser Vorlage werden an Benutzer gesendete Bestätigungscodes gespeichert.
# 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 < timezone.now() - timedelta(minutes=10) # Expire après 10 minutes def __str__(self): return f"Vérification de {self.user.email} - {'Validé' if self.is_verified else 'En attente'}"
Sie können Twilio zum Senden von Textnachrichten verwenden. Erstellen Sie zunächst ein Twilio-Konto und besorgen Sie sich die erforderlichen Anmeldeinformationen (ACCOUNT_SID, AUTH_TOKEN, FROM_NUMBER).
Fügen Sie diese Konfigurationen zu Ihrer Settings.py hinzu:
# settings.py TWILIO_ACCOUNT_SID = 'votre_account_sid' TWILIO_AUTH_TOKEN = 'votre_auth_token' TWILIO_FROM_NUMBER = '+1234567890' # Numéro Twilio
Erstellen Sie eine utils.py-Datei, um den SMS-Versand zu verwalten:
# 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
Erstellen Sie Serialisierer, um die Verifizierungsanfrage und Codevalidierung zu verarbeiten.
pip install djangorestframework twilio django-phonenumber-field
Erstellen Sie Ansichten, um Verifizierungsanfragen und Codevalidierung zu verwalten.
# settings.py INSTALLED_APPS = [ # ... 'rest_framework', 'phonenumber_field', # ... ]
Hinweis: Möglicherweise möchten Sie diese Ansichten nach Bedarf anpassen, beispielsweise wenn Sie während der Überprüfung einen Benutzer erstellen oder vorhandene Benutzer anders verwalten möchten.
Fügen Sie die entsprechenden Routen in Ihre urls.py ein.
# 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
Bearbeiten Sie die Anforderungsansicht, um den Code einem bestimmten Benutzer zuzuordnen oder einen neuen Benutzer zu erstellen.
Um Missbrauch zu vermeiden, begrenzen Sie die Anzahl der Verifizierungsanfragen pro Benutzer oder Telefonnummer.
# 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 < timezone.now() - timedelta(minutes=10) # Expire après 10 minutes def __str__(self): return f"Vérification de {self.user.email} - {'Validé' if self.is_verified else 'En attente'}"
Sie können nach der Überprüfung entscheiden, einen Benutzer zu erstellen oder die Nummer einem vorhandenen Benutzer zuzuordnen.
Testen Sie Ihr System unbedingt in einer Entwicklungsumgebung, bevor Sie es in der Produktion bereitstellen. Überprüfen Sie Folgendes:
Um Ihnen einen Überblick zu geben, finden Sie hier ein vollständiges Beispiel der betroffenen Dateien.
# settings.py TWILIO_ACCOUNT_SID = 'votre_account_sid' TWILIO_AUTH_TOKEN = 'votre_auth_token' TWILIO_FROM_NUMBER = '+1234567890' # Numéro Twilio
# 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
# 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
# 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)
# 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'), ]
Überprüfungsversuche begrenzen: Implementieren Sie ein System, um die Anzahl der Überprüfungsversuche zu begrenzen, um Brute-Force-Angriffe zu vermeiden.
Codes verschlüsseln: Für zusätzliche Sicherheit können Sie die Bestätigungscodes in der Datenbank verschlüsseln.
Asynchrone Aufgaben verwenden: Um die Leistung zu verbessern, verwenden Sie asynchrone Aufgaben (z. B. mit Celery), um SMS zu senden, ohne API-Anfragen zu blockieren.
HTTPS konfigurieren: Stellen Sie sicher, dass Ihre API über HTTPS zugänglich ist, um die Kommunikation zu sichern.
Das obige ist der detaillierte Inhalt vonImplementierung der Telefonnummernüberprüfung in einem DRF-Projekt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!