• 登录, 发送验证码接口, 对官方提供的短信SDK进行二次封装


    登录

    1.设计数据库表 2.根据需求设计接口 3.书写代码完成接口功能

    • 账号(手机号, 用户名, 邮箱)密码登录

      1. 输入账号密码, 向账号密码登录接口发送post请求
      2. 校验通过后签发token
    • 手机号验证码登录

      1. 输入手机号
      2. 点击发送验证码按钮, 向发送验证码接口发送get请求
      3. 输入验证码, 向手机号验证码登录接口发送post请求
      4. 从django缓存中取出验证码进行校验, 校验通过后签发token
      '''
      # ...luffyapiluffyapiappsuserurls.py
      ...
      urlpatterns = [
          ...,
          path('code/login/', views.CodeLoginAPIView.as_view()),  # 手机号 + 验证码登录接口
      ]
      
      
      # ...luffyapiluffyapiappsuserviews.py
      from rest_framework_jwt.views import JSONWebTokenAPIView
      from . import my_serializers
      
      
      class CodeLoginAPIView(JSONWebTokenAPIView):
          serializer_class = my_serializers.CodeLoginSerializer
          
      
      # ...luffyapiluffyapiappsusermy_serializers.py
      ...
      from rest_framework import serializers
      
      
      class CodeLoginSerializer(serializers.Serializer):
          code = serializers.CharField(min_length=6, max_length=6)
          mobile = serializers.CharField(min_length=11, max_length=11)
      
          def validate(self, attrs):
              mobile = attrs.get('mobile')
              code = attrs.get('code')
      
              if not code.isdigit():  # 校验验证码是否为纯数字, 否则直接抛错, 减少缓存io
                  raise serializers.ValidationError('验证码不为纯数字')
              cache_code = cache.get(settings.CODE_CACHE_FORMAT % mobile)  # 获取服务器缓存的验证码
              if code != cache_code:
                  raise serializers.ValidationError('验证码有误')
      
              try:
                  user = models.User.objects.get(mobile=mobile, is_active=True)
              except:
                  raise serializers.ValidationError('该手机号尚未注册')
      
              payload = jwt_payload_handler(user)  
      
              token = jwt_encode_handler(payload) 
      
              self.object = {'token': token, 'user': user}  
              
              cache.delete(settings.CODE_CACHE_FORMAT % mobile)  # 手机号 + 验证码登录成功后删除django中缓存的验证码 
      
              return attrs
      '''
      

    发送验证码接口

    1. 产生验证码
    2. 将验证码交给腾讯云发送
    3. 阅读腾讯云的短信API文档
    4. 对官方提供的短信SDK进行二次封装
    5. 短信发送成功后将产生的验证码存到django缓存中
    '''
    # ...luffyapiluffyapiappsuserurls.py
    ...
    urlpatterns = [
        ...
        path('code/send/', views.SendSmsAPIView.as_view()),  # 发送验证码接口
    ]
    
    
    # ...luffyapiluffyapiappsuserviews.py
    ...
    from luffyapi.libs.sms_sdk import send_sms
    from luffyapi.utils.sms_code import generate_code
    from django.core.cache import cache
    from django.conf import settings
    from rest_framework.response import Response
    
    
    class SendSmsAPIView(APIView):
        authentication_classes = []
        permission_classes = []
    
        def get(self, request, *args, **kwargs):  # get请求的处理效率要高于post请求
            mobile = request.query_params.get('mobile')
            if not mobile:
                return Response(data={'code': 1001, 'detail': 'mobile字段必须提供'}, status=400)
            if not re.match(r'^1[3-9][0-9]{9}$', mobile):
                return Response(data={'code': 1002, 'detail': '手机号格式有误'}, status=400)
    
            code = generate_code()
    
            res = send_sms([mobile, ], code, settings.CODE_EXP // 60)  # 短信验证码的过期时间以分钟为单位
            if not res:
                return Response(data={'code': 1003, 'detail': '验证码发送失败'}, status=500)
    
            cache.set(settings.CODE_CACHE_FORMAT % mobile, code, settings.CODE_EXP)  # django缓存的过期时间以秒为单位
    
            return Response(data={'code': 0, 'msg': '验证码发送成功', })
            
            
    # ...luffyapiluffyapiutilssms_code.py
    # 产生六位随机数字验证码
    def generate_code():
        import random
        lt = []
        for i in range(10):
            lt.append(str(i))
        rand_lt = random.sample(lt, 6)
        code = ''.join(rand_lt)
        return code
    
    
    # ...luffyapiluffyapisettingsconst_settings.py
    ...
    CODE_CACHE_FORMAT = 'code_cache_%s'  # 验证码缓存key
    
    CODE_EXP = 30000  # 验证码过期时间
    '''
    

    对官方提供的短信SDK进行二次封装

    '''
    # ...luffyapiluffyapilibssms_sdksettings.py
    ...  # 调用发送验证码方法需要的固定配置
    
    
    # ...luffyapiluffyapilibssms_sdksingle_send.py
    from qcloudsms_py import SmsSingleSender
    from .settings import TEMPLATE_ID, SMS_SIGN, APPID, APPKEY
    from luffyapi.utils.my_logging import logger
    
    
    # 发送验证码
    def send_sms(phone_num_lt, code, exp):
        try:
            sender = SmsSingleSender(APPID, APPKEY)
            response = sender.send_with_param(86, phone_num_lt[0], TEMPLATE_ID, (code, exp), sign=SMS_SIGN, extend="", ext="")
            # print(response)  # {'result': 0, 'errmsg': 'OK', 'ext': '', 'sid': '8:rIcypgwqRVSqRCVVJ0e20200113', 'fee': 1}
    
            if response.get('result') != 0:
                logger.error('验证码发送失败, "code": %s, "detail": %s' % (response.get('result'), response.get('errmsg')))
                return False
            return True
    
        except Exception as e:
            logger.error('代码运行异常, "detail": %s' % e)
            
    
    # ...luffyapiluffyapilibssms_sdk\__init__.py
    from .single_send import send_sms  # 面向包封装
    '''
    
  • 相关阅读:
    阿里云服务器,http免费转https详细教程
    springboot系列总结(二)---springboot的常用注解
    springboot系列总结(一)---初识springboot
    java 查询当天0点0分0秒
    mysql各个版本驱动jar包下载 mysql/mysql-connector-java/5.1.22
    泰坦尼克 学习
    切片
    忽略warning 警告
    迭代 递归 循环 遍历
    标准化 归一化
  • 原文地址:https://www.cnblogs.com/-406454833/p/12709285.html
Copyright © 2020-2023  润新知