五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動態(tài)

Python編程使用DRF實現(xiàn)一次性驗證碼OTP

發(fā)布日期:2022-01-04 02:14 | 文章來源:站長之家

一次性驗證碼,英文是 One Time Password,簡寫為 OTP,又稱動態(tài)密碼或單次有效密碼,是指計算機系統(tǒng)或其他數字設備上只能使用一次的密碼,有效期為只有一次登錄會話或很短如 1 分鐘。OTP 避免了一些靜態(tài)密碼認證相關系的缺點,不容易受到重放攻擊,比如常見的注冊場景,用戶的郵箱或短信會收到一條一次性的激活鏈接,或者收到一次隨機的驗證碼(只能使用一次),從而驗證了郵箱或手機號的有效性。

要實現(xiàn)的功能就是:

1、驗證碼是 6 位的數字和小寫字母的組合。

2、有效期為 5 分鐘,第二次發(fā)送驗證碼的必須在 1 分鐘之后。

3、如果該郵箱/手機號已經注冊,則不能發(fā)送注冊驗證碼。

具體的實現(xiàn)邏輯就是:

1、先生成滿足條件的驗證碼。

2、發(fā)送前驗證,是否上次發(fā)送的驗證碼在 1 分鐘之內?是否郵箱已經注冊?,如果是,拒絕發(fā)送,并提示用戶,如果否,發(fā)送驗證碼。

3、驗證,是否是 5 分鐘之內的驗證碼,是否正確,如果是,則放行。否則提示用戶。

為了驗證驗證碼及其時效,我們需要把發(fā)送驗證碼的時間和對應的郵箱記錄下來,那么就需要設計一張表來存儲。

class VerifyCode(models.Model):
 mobile = models.CharField(max_length=11, verbose_name="手機號", blank=True)
 email = models.EmailField(verbose_name="email", blank=True)
 code = models.CharField(max_length=8, verbose_name="驗證碼")
 add_time = models.DateTimeField(verbose_name='生成時間', auto_now_add=True)

1、生成驗證碼

第一個邏輯非常簡單,可以直接寫出代碼:

from random import choice
 def generate_code(self):
 """
 生成 6 位數驗證碼,防止破解
 :return:
 """
 seeds = "1234567890abcdefghijklmnopqrstuvwxyz"
 random_str = []
 for i in range(6):
  random_str.append(choice(seeds))
 return "".join(random_str)

2、發(fā)送前驗證

Django REST framework 框架的 Serializer 可以對 Models 里的每一個字段進行驗證,我們直接在里面做填空題即可:

# serializers.py
class VerifyCodeSerializer(serializers.Serializer):
 email = serializers.EmailField(required=True)
 def validate_email(self, email):
  """
  驗證郵箱是否合法
  """
  # 郵箱是否注冊
  if User.objects.filter(email = email).count():
raise serializers.ValidationError('該郵箱已經注冊')
# 驗證郵箱號碼合法
  if not re.match(EMAIL_REGEX, email):
raise serializers.ValidationError('郵箱格式錯誤')
# 驗證碼發(fā)送頻率
  one_minute_age = datetime.now() - timedelta(hours=0, minutes=1, seconds=0)
  if VerifyCode.objects.filter(add_time__gt=one_minute_age, email=email).count():
raise serializers.ValidationError('請一分鐘后再次發(fā)送')
  return email
 

3、發(fā)送驗證碼

發(fā)送驗證碼,其實就是生成驗證碼并保存的過程,借助于 Django REST framework 框架的 GenericViewSet 和 CreateModelMixin 即可實現(xiàn) view 類,代碼都有詳細的注釋,你很容易就看明白:

from rest_framework.response import Response
from rest_framework.views import status
from rest_framework import mixins, viewsets
class VerifyCodeViewSet(viewsets.GenericViewSet, mixins.CreateModelMixin):
 """
 發(fā)送驗證碼
 """
 permission_classes = [AllowAny] #允許所有人注冊
 serializer_class = VerifyCodeSerializer #相關的發(fā)送前驗證邏輯
 def generate_code(self):
  """
  生成6位數驗證碼 防止破解
  :return:
  """
  seeds = "1234567890abcdefghijklmnopqrstuvwxyz"
  random_str = []
  for i in range(6):
random_str.append(choice(seeds))
  return "".join(random_str)
 def create(self, request, *args, **kwargs):
  # 自定義的 create() 的內容
  serializer = self.get_serializer(data=request.data)
  serializer.is_valid(raise_exception=True) #這一步相當于發(fā)送前驗證
  # 從 validated_data 中獲取 mobile
  email = serializer.validated_data["email"]
  # 隨機生成code
  code = self.generate_code()
  # 發(fā)送短信或郵件驗證碼
  sms_status = SendVerifyCode.send_email_code(code=code, to_email_adress=email)
if sms_status == 0:
# 記錄日志
 
return Response({"msg": "郵件發(fā)送失敗"}, status=status.HTTP_400_BAD_REQUEST)
  else:
code_record = VerifyCode(code=code, email=email)
# 保存驗證碼
code_record.save()
return Response(
 {"msg": f"驗證碼已經向 {email} 發(fā)送完成"}, status=status.HTTP_201_CREATED
)
 

SendVerifyCode.send_email_code 的實現(xiàn)如下:

#encoding=utf-8
from django.core.mail import send_mail
class SendVerifyCode(object):
 @staticmethod
 def send_email_code(code,to_email_adress):
  try:
success_num = send_mail(subject='xxx 系統(tǒng)驗碼', message=f'您的驗證碼是【[code]】。如非本人操作,請忽略。',from_email='xxxx@163.com',recipient_list = [to_email_adress], fail_silently=False)
return success_num
  except:
return 0

4、注冊時驗證

用戶注冊對于數據庫來講就是 User 類插入一條記錄,也就是 User 的 view 類的 create 操作來實現(xiàn)注冊。

from .serializers import UserRegisterSerializer, UserSerializer
class UserViewSet(viewsets.ModelViewSet):
 """
 API endpoint that allows users to be viewed or edited.
 """
 serializer_class = UserSerializer
 
 def get_serializer_class(self):
  if self.action == "create":
# 如果是創(chuàng)建用戶,那么用 UserRegisterSerializer
serializer_class = UserRegisterSerializer
  else:
serializer_class = UserSerializer
  return serializer_class

這個骨架好了以后,我們現(xiàn)在來編寫 UserRegisterSerializer 類,實現(xiàn)注冊時驗證:

# serializers.py
class UserRegisterSerializer(serializers.ModelSerializer):
 # error_message:自定義錯誤消息提示的格式
 code = serializers.CharField(required=True, allow_blank=False, min_length=6, max_length=6, help_text='驗證碼',
  error_messages={
'blank': '請輸入驗證碼',
'required': '請輸入驗證碼',
'min_length': '驗證碼格式錯誤',
'max_length': '驗證碼格式錯誤',
  }, write_only=True)
 # 利用drf中的validators驗證username是否唯一
 username = serializers.CharField(required=True, allow_blank=False,
validators=[UniqueValidator(queryset=User.objects.all(), message='用戶已經存在')])
 email = serializers.EmailField(required=True, allow_blank=False,
 validators=[UniqueValidator(queryset=User.objects.all(), message='郵箱已被注冊')])
  # 對code字段單獨驗證(validate_+字段名)
 def validate_code(self, code):
  verify_records = VerifyCode.objects.filter(email=self.initial_data['email']).order_by('-add_time')
  if verify_records:
last_record = verify_records[0]
# 判斷驗證碼是否過期
five_minutes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)  # 獲取5分鐘之前的時間
if last_record.add_time < five_minutes_ago:
 raise serializers.ValidationError('驗證碼過期')
# 判斷驗證碼是否正確
if last_record.code != code:
 raise serializers.ValidationError('驗證碼錯誤')
# 不用將code返回到數據庫中,只是做驗證
# return code
  else:
raise serializers.ValidationError('驗證碼不存在')
 # attrs:每個字段validate之后總的dict
 def validate(self, attrs):
  # attrs['mobile'] = attrs['username']
  # 從attrs中刪除code字段
  del attrs['code']
  return attrs
 class Meta:
  model = User
  fields = ('username', 'email', 'password', 'code')
  extra_kwargs = {'password': {'write_only': True}}
 def create(self, validated_data):
  user = User(
email=validated_data['email'],
username=validated_data['username']
  )
  user.set_password(validated_data['password'])
  user.save()
  return user

至此發(fā)送驗證碼的后端編碼已經結束。

最后的話

一次性驗證碼(OTP)的邏輯簡單,需要思考的是如何在 DRF 的框架中填空,填在哪里?這其實需要了解 DRF 的 ModelSerializer 類和 ViewSet 類之前的關系,在調用關系上,ViewSet 類調用 ModelSerializer 來實現(xiàn)字段的驗證和數據保存及序列化,Serializers 類不是必須的,你可以完全自己實現(xiàn)驗證和數據保存及序列化,只不過這樣會導致 View 類特別臃腫,不夠優(yōu)雅,不易維護。

參考資料

[1]

Django REST framework:https://www.django-rest-framework.org

以上就是Python編程使用DRF實現(xiàn)一次性驗證碼OTP的詳細內容,更多關于Python編程DRF一次性驗證碼OTP的資料請關注本站其它相關文章!

版權聲明:本站文章來源標注為YINGSOO的內容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網站,禁止在非maisonbaluchon.cn所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內容來源于網友推薦、互聯(lián)網收集整理而來,僅供學習參考,不代表本站立場,如有內容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。

相關文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務

7x24全年不間斷在線

專屬顧問服務

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務熱線

關注
微信

關注官方微信
頂部