• 【DJango项目】2.短信验证码 后端逻辑代码实现 celery异步 跨域问题解决


    访问方式 GET /sms_codes/{mobile}/?imange_code_id=xxx& text=xxx

    返回数据: message str OK发送成功 

    序列化器 

    class CheckImageCodeSerializer(serializers.Serializer):
        """
        图片验证码校验序列化器
        """
        # 从页面获取 验证码id号
        image_code_id = serializers.UUIDField()
        # 从页面获取 验证码
        text = serializers.CharField(min_length=4, max_length=4)
    
        def validate(self, attrs):
            """
            校验图片验证码用户是否正确
            :param attrs:
            :return:
            """
            image_code_id = attrs["image_code_id"]
            text = attrs["text"]
    
            # 查询redis数据库 获取真实的验证码
            redis_conn = get_redis_connection("verify_codes")
            real_image_code = redis_conn.get("img_%s" % image_code_id)
    
            if real_image_code is None:
                # 过期或者不存在
                raise serializers.ValidationError('无效的图片验证码')
    
            # 删除redis中的图片验证码 防止用户对同一个用户多次请求验证
            # 如果删除错误就跳过 如果不跳过就会抛异常  下面都不会执行
            try:
                redis_conn.delete('img_%s' % image_code_id)
            except RedisError as e:
                logger.error(e)
    
            # 对比
            real_image_code = real_image_code.decode()
            if real_image_code.lower() != text.lower():
                raise serializers.ValidationError("图片验证码错误")
    
            # redis中发送短信验证码的标志 send_flag_<mobile> :1,由redis维护60s
            mobile = self.context['view'].kwargs['mobile']
            send_flag = redis_conn.get("send_flag_%s" % mobile)
            if send_flag:
                raise serializers.ValidationError("发送短信过于频繁")
    
            return attrs

    视图

    class SMSCodeView(GenericAPIView):
        serializer_class = serializers.CheckImageCodeSerializer
    
        def get(self, request, mobile):
            # 校验图片验证码和发送短信的频次
            # mobile 被放到类视图对象当中 属性kwargs
            serializer = self.get_serializer(data=request.query_params)
            serializer.is_valid(raise_exception=True)
    
            # 校验通过 生成短息验证码
            sms_code = '%06d' % random.randint(0, 999999)
    
            # 保存验证码及发送记录
            redis_conn = get_redis_connection('verify_codes')
    
            # redis_conn.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
            # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
    
            # 使用redis pipeline管道 一次执行多个命令
            pl = redis_conn.pipline()
            pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
            pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
            # 让管道执行命令
            pl.execute()
    
            # 发送短信
            ccp = CCP()
            time = constants.SMS_CODE_REDIS_EXPIRES / 60
            ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_CODE_TEMP_ID)
    
            # 返回
            return Response({'message': 'OK'}, status=200)

    Django 异步发起者   ----------------> Redis broker 任务列表  ---------------->  Celey 异步发送短信

                                            ---------> backend(保存异步结果) <-----------

    目录: celery_task 

          ---sms   # 任务目录

            ---tasks.py    # 执行任务函数

          __init__.py

          config.py  # 配置文件 

          main.py   # 执行文件

    安装 : pip  install -U Celery 

    config.py

    broker_url = "redis://127.0.0.1/14"
    result_backend = "redis://127.0.0.1/15"

    main.py

    from celery import Celery
    
    celery_app = Celery("meiduo")
    
    # 导入配置文件
    celery_app.config_from_object("celery_task.config")
    
    # 自动注册celery任务
    celery_app.autodiscover_tasks(['celery_tasks.sms'])

    解决跨域问题

    pip install django-cors-headers 

    MIDDLEWARE = [
    'corsheaders.middleware.CoresMiddleware',
    ]

    INSTALLED_APPS = [
       'corsheaders',
    ]

    白名单配置 :
    # CORS
    CORS_ORIGIN_WHITELIST = (
        'http://127.0.0.1:8080',
        'http://localhost:8080',
        'www.meiduo.site:8080'
    )
    CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

    参考 https://blog.csdn.net/qq_42799459/article/details/90611119

    未完待续 

  • 相关阅读:
    linux下查看jdk路径
    mysql内部级联删除
    Mybatis Mapper.java和Mapper.xml能否分离问题
    The request sent by the client was syntactically incorrect问题解决
    centos下-MariaDB的安装
    对于mariadb安装后可以默认使用无密码登录的问题解决方案
    C#复习笔记(2)--C#1所搭建的核心基础
    C#精粹--协变和逆变
    linux和sqlserver 2017的安装
    C#精粹--闭包陷阱
  • 原文地址:https://www.cnblogs.com/oscarli/p/12358729.html
Copyright © 2020-2023  润新知