亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 後端開發(fā) Python教學(xué) 在drf專案中實(shí)現(xiàn)電話號碼驗(yàn)證

在drf專案中實(shí)現(xiàn)電話號碼驗(yàn)證

Dec 28, 2024 am 10:17 AM

Implémentation de vérification de numéro de téléphone dans un projet drf

要使用 Django REST Framework (DRF) 實(shí)作電話號碼驗(yàn)證系統(tǒng),您可以依照下列步驟操作。該系統(tǒng)將允許用戶提供他們的電話號碼,透過簡訊接收驗(yàn)證碼(例如透過 Twilio),並驗(yàn)證此代碼以驗(yàn)證他們的號碼。

主要步驟:

  1. 安裝必要的依賴項(xiàng)
  2. 編輯使用者範(fàn)本以包含電話號碼
  3. 建立範(fàn)本來儲存驗(yàn)證碼
  4. 設(shè)定簡訊發(fā)送服務(wù)(例如 Twilio)
  5. 建立 DRF 序列化器
  6. 建立視圖和 API 路由
  7. 管理驗(yàn)證邏輯與安全性

1.安裝必要的依賴項(xiàng)

首先,請確保您已經(jīng)安裝了必要的庫:

  • Django REST Framework:如果您還沒有。
  • Twilio:用於發(fā)送簡訊。
  • django-phonenumber-field:用於驗(yàn)證和格式化電話號碼。

透過 pip 安裝它們:

pip install djangorestframework twilio django-phonenumber-field

將phonenumber_field和rest_framework加入settings.py中的INSTALLED_APPS中:

# settings.py

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'phonenumber_field',
    # ...
]

2. 更改使用者範(fàn)本以包含電話號碼

如果您使用自訂使用者模板,請新增電話號碼欄位和驗(yàn)證標(biāo)誌。

# 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

注意:如果您已有使用者模型,請務(wù)必適當(dāng)新增phone_number 和 is_phone_verified 欄位。

3. 建立模板儲存驗(yàn)證碼

此範(fàn)本將儲存空間傳送給使用者的驗(yàn)證碼。

# 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'}"

4. 設(shè)定簡訊發(fā)送服務(wù)(例如 Twilio)

您可以使用 Twilio 發(fā)送簡訊。首先建立一個(gè) Twilio 帳戶並取得必要的憑證(ACCOUNT_SID、AUTH_TOKEN、FROM_NUMBER)。

將這些配置加入到您的settings.py中:

# settings.py

TWILIO_ACCOUNT_SID = 'votre_account_sid'
TWILIO_AUTH_TOKEN = 'votre_auth_token'
TWILIO_FROM_NUMBER = '+1234567890'  # Numéro Twilio

建立utils.py檔案來管理發(fā)送簡訊:

# 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. 建立 DRF 序列化器

建立序列化器來處理驗(yàn)證請求和程式碼驗(yàn)證。

pip install djangorestframework twilio django-phonenumber-field

6. 建立API視圖和路由

建立視圖來管理驗(yàn)證請求和程式碼驗(yàn)證。

# settings.py

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'phonenumber_field',
    # ...
]

注意:您可能需要根據(jù)需要調(diào)整這些視圖,例如您想要在驗(yàn)證過程中建立使用者或以不同方式管理現(xiàn)有使用者。

7. 設(shè)定API路由

在你的urls.py中加入對應(yīng)的路由。

# 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. 新增附加邏輯(可選)

有。為每個(gè)使用者產(chǎn)生唯一代碼

編輯請求視圖以將程式碼與特定使用者關(guān)聯(lián)或建立新使用者。

b.限制請求數(shù)量

為避免濫用,請限制每個(gè)使用者或電話號碼的驗(yàn)證請求數(shù)量。

# 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'}"

c.驗(yàn)證過程中的使用者管理

您可以在驗(yàn)證後決定建立使用者或?qū)⑻柎a與現(xiàn)有使用者關(guān)聯(lián)。

9. 測試和驗(yàn)證

在將系統(tǒng)部署到生產(chǎn)環(huán)境之前,請務(wù)必在開發(fā)環(huán)境中測試您的系統(tǒng)。檢查:

  • 簡訊已正確發(fā)送。
  • 程式碼是安全產(chǎn)生和儲存的。
  • 支票在設(shè)定時(shí)間後過期。
  • 錯(cuò)誤被正確處理並傳達(dá)給使用者。

完整的實(shí)施範(fàn)例

為了給您一個(gè)概述,這裡是受影響文件的完整範(fàn)例。

模型.py

# settings.py

TWILIO_ACCOUNT_SID = 'votre_account_sid'
TWILIO_AUTH_TOKEN = 'votre_auth_token'
TWILIO_FROM_NUMBER = '+1234567890'  # Numéro Twilio

序列化器.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

視圖.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)

實(shí)用程式.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. 安全和優(yōu)化

  • 限制驗(yàn)證嘗試:實(shí)施一個(gè)系統(tǒng)來限制驗(yàn)證嘗試的次數(shù),以避免暴力攻擊。

  • 加密代碼:為了增加安全性,您可以將資料庫中的驗(yàn)證碼加密。

  • 使用非同步任務(wù):要提高效能,請使用非同步任務(wù)(例如使用 Celery)發(fā)送短信,而不會阻塞 API 請求。

  • 設(shè)定 HTTPS: 確保您的 API 可透過 HTTPS 存取以確保通訊安全。

以上是在drf專案中實(shí)現(xiàn)電話號碼驗(yàn)證的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Python類中的多態(tài)性 Python類中的多態(tài)性 Jul 05, 2025 am 02:58 AM

多態(tài)是Python面向?qū)ο缶幊讨械暮诵母拍睿浮耙环N接口,多種實(shí)現(xiàn)”,允許統(tǒng)一處理不同類型的對象。 1.多態(tài)通過方法重寫實(shí)現(xiàn),子類可重新定義父類方法,如Animal類的speak()方法在Dog和Cat子類中有不同實(shí)現(xiàn)。 2.多態(tài)的實(shí)際用途包括簡化代碼結(jié)構(gòu)、增強(qiáng)可擴(kuò)展性,例如圖形繪製程序中統(tǒng)一調(diào)用draw()方法,或遊戲開發(fā)中處理不同角色的共同行為。 3.Python實(shí)現(xiàn)多態(tài)需滿足:父類定義方法,子類重寫該方法,但不要求繼承同一父類,只要對象實(shí)現(xiàn)相同方法即可,這稱為“鴨子類型”。 4.注意事項(xiàng)包括保持方

Python函數(shù)參數(shù)和參數(shù) Python函數(shù)參數(shù)和參數(shù) Jul 04, 2025 am 03:26 AM

參數(shù)(parameters)是定義函數(shù)時(shí)的佔(zhàn)位符,而傳參(arguments)是調(diào)用時(shí)傳入的具體值。 1.位置參數(shù)需按順序傳遞,順序錯(cuò)誤會導(dǎo)致結(jié)果錯(cuò)誤;2.關(guān)鍵字參數(shù)通過參數(shù)名指定,可改變順序且提高可讀性;3.默認(rèn)參數(shù)值在定義時(shí)賦值,避免重複代碼,但應(yīng)避免使用可變對像作為默認(rèn)值;4.args和*kwargs可處理不定數(shù)量的參數(shù),適用於通用接口或裝飾器,但應(yīng)謹(jǐn)慎使用以保持可讀性。

解釋Python發(fā)電機(jī)和迭代器。 解釋Python發(fā)電機(jī)和迭代器。 Jul 05, 2025 am 02:55 AM

迭代器是實(shí)現(xiàn)__iter__()和__next__()方法的對象,生成器是簡化版的迭代器,通過yield關(guān)鍵字自動實(shí)現(xiàn)這些方法。 1.迭代器每次調(diào)用next()返回一個(gè)元素,無更多元素時(shí)拋出StopIteration異常。 2.生成器通過函數(shù)定義,使用yield按需生成數(shù)據(jù),節(jié)省內(nèi)存且支持無限序列。 3.處理已有集合時(shí)用迭代器,動態(tài)生成大數(shù)據(jù)或需惰性求值時(shí)用生成器,如讀取大文件時(shí)逐行加載。注意:列表等可迭代對像不是迭代器,迭代器到盡頭後需重新創(chuàng)建,生成器只能遍歷一次。

python`@classmethod'裝飾師解釋了 python`@classmethod'裝飾師解釋了 Jul 04, 2025 am 03:26 AM

類方法是Python中通過@classmethod裝飾器定義的方法,其第一個(gè)參數(shù)為類本身(cls),用於訪問或修改類狀態(tài)。它可通過類或?qū)嵗{(diào)用,影響的是整個(gè)類而非特定實(shí)例;例如在Person類中,show_count()方法統(tǒng)計(jì)創(chuàng)建的對像數(shù)量;定義類方法時(shí)需使用@classmethod裝飾器並將首參命名為cls,如change_var(new_value)方法可修改類變量;類方法與實(shí)例方法(self參數(shù))、靜態(tài)方法(無自動參數(shù))不同,適用於工廠方法、替代構(gòu)造函數(shù)及管理類變量等場景;常見用途包括從

如何處理Python中的API身份驗(yàn)證 如何處理Python中的API身份驗(yàn)證 Jul 13, 2025 am 02:22 AM

處理API認(rèn)證的關(guān)鍵在於理解並正確使用認(rèn)證方式。 1.APIKey是最簡單的認(rèn)證方式,通常放在請求頭或URL參數(shù)中;2.BasicAuth使用用戶名和密碼進(jìn)行Base64編碼傳輸,適合內(nèi)部系統(tǒng);3.OAuth2需先通過client_id和client_secret獲取Token,再在請求頭中帶上BearerToken;4.為應(yīng)對Token過期,可封裝Token管理類自動刷新Token;總之,根據(jù)文檔選擇合適方式,並安全存儲密鑰信息是關(guān)鍵。

什麼是python魔法方法或dunder方法? 什麼是python魔法方法或dunder方法? Jul 04, 2025 am 03:20 AM

Python的magicmethods(或稱dunder方法)是用於定義對象行為的特殊方法,它們以雙下劃線開頭和結(jié)尾。 1.它們使對象能夠響應(yīng)內(nèi)置操作,如加法、比較、字符串表示等;2.常見用例包括對像初始化與表示(__init__、__repr__、__str__)、算術(shù)運(yùn)算(__add__、__sub__、__mul__)及比較運(yùn)算(__eq__、__lt__);3.使用時(shí)應(yīng)確保其行為符合預(yù)期,例如__repr__應(yīng)返回可重構(gòu)對象的表達(dá)式,算術(shù)方法應(yīng)返回新實(shí)例;4.應(yīng)避免過度使用或以令人困惑的方

Python內(nèi)存管理如何工作? Python內(nèi)存管理如何工作? Jul 04, 2025 am 03:26 AM

Pythonmanagesmemoryautomaticallyusingreferencecountingandagarbagecollector.Referencecountingtrackshowmanyvariablesrefertoanobject,andwhenthecountreacheszero,thememoryisfreed.However,itcannothandlecircularreferences,wheretwoobjectsrefertoeachotherbuta

python`@property`裝飾師 python`@property`裝飾師 Jul 04, 2025 am 03:28 AM

@property是Python中用於將方法偽裝成屬性的裝飾器,允許在訪問屬性時(shí)執(zhí)行邏輯判斷或動態(tài)計(jì)算值。 1.它通過@property裝飾器定義getter方法,使外部像訪問屬性一樣調(diào)用方法;2.搭配.setter可控制賦值行為,如校驗(yàn)值合法性,不定義.setter則為只讀屬性;3.適用於屬性賦值校驗(yàn)、動態(tài)生成屬性值、隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié)等場景;4.使用時(shí)注意屬性名與私有變量名不同名,避免死循環(huán),適合輕量級操作;5.示例中Circle類限制radius非負(fù),Person類動態(tài)生成full_name屬

See all articles