Example #1
0
    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_{}'.format(mobile),constants.SMS_CODE_REDIS_EXPIRES,sms_code)
        # redis_conn.setex('send_flag_{}'.format(mobile),constants.SEND_SMS_CODE_INTERVAL,1)
        # 使用redis的pipeline管道一次执行多个命令
        pl = redis_conn.pipeline()
        pl.setex('sms_{}'.format(mobile),constants.SMS_CODE_REDIS_EXPIRES,sms_code)
        pl.setex('send_flag_{}'.format(mobile),constants.SEND_SMS_CODE_INTERVAL,1)
        # 让管道执行命令
        pl.execute()

        # 发送短信
        # ccp = CCP()
        # ccp.send_tempate_sms(mobile,[sms_code,"5"],constants.SMS_CODE_TEMP_ID)
        # 使用celery发布异步任务
        send_sms_code.delay(mobile,sms_code)

        # 返回
        return Response({'message':'OK'})
Example #2
0
    def get(self, request, mobile):
        """
        校验图片验证码和发送短信的频次
        mobile是被放到了类视图对象属性kwaargs中
        """
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        # 校验通过
        # 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)
        print(sms_code)
        # 保存短信验证码与发送记录
        redis_conn = get_redis_connection('verify_codes')

        # 保存验证码及发送记录
        # 使用redis的pipeline管道一次执行多条命令
        pl = redis_conn.pipeline()
        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 = str(constants.SMS_CODE_REDIS_EXPIRES // 60)
        # ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_CODE_TEMP_ID)
        # 使用celery发布异步任务
        send_sms_code.delay(mobile, sms_code)

        # 返回
        return Response({"message": "OK"})
Example #3
0
    def get(self, request, mobile):
        # 0.创建redis连接对象
        redis_conn = get_redis_connection('verify_codes')
        # 1.获取此手机号是否有发送过的标记
        flag = redis_conn.get('send_flag_%s' % mobile)
        # 2.如果已发送就提前响应,不执行后续代码
        if flag:  # 如果if成立说明此手机号60秒内发过短信
            return Response({'message': '频繁发送短信'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 3.生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        # 创建redis管道对象
        pl = redis_conn.pipeline()

        # 4.把验证码存储到redis中
        # redis_conn.setex(key, 过期时间, value)
        # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 4.1 存储此手机号已发送短信标记
        # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

        # 执行管道
        pl.execute()

        # 5.利用容联云通讯发短信
        # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)
        # 触发异步任务(让发短信不要阻塞主线程)
        # send_sms_code(mobile, sms_code)
        send_sms_code.delay(mobile, sms_code)
        # 6.响应
        return Response({'message': 'ok'})
Example #4
0
    def get(self, request, mobile):
        # 校验图片验证码和发送短信的频次
        # mobile是被放到了类视图对象属性kwargs中
        # mobile在url的正则中验证
        # 所以反序列化的data中只传查询参数 query_params
        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.pipeline()
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 60S来控制已经发送短信
        # 让管道执行命令
        pl.execute()

        # 发送短信
        # ccp = CCP()
        # time = str(constants.SMS_CODE_REDIS_EXPIRES / 60)
        # ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_CODE_TEMP_ID)
        # 使用celery发布异步任务
        send_sms_code.delay(mobile, sms_code)
        print(sms_code)
        # 返回
        return Response({'message': 'OK'})
Example #5
0
    def post(self, request):
        # 校验手机号码
        mobile = request.data.get("mobile")
        mobile = re.match("1[3-9][0-9]{9}$", mobile)
        if not mobile:
            return Response(data={"code": "400", "messages": "手机号码格式错误"})
        mobile = mobile.group()
        # 查询手机号是否被注册
        user = User.objects.filter(mobile=mobile)
        if user:
            return Response(data={"messages": "手机号码已经被注册"})
        # 校验是否频繁发送
        redis_conn = get_redis_connection(
            alias="verify_codes")  # type:StrictRedis
        send_flag = redis_conn.get("%s_flag" % mobile)
        if send_flag:
            # 短信验证码存在
            return Response(data={"messages": "请求频繁"})

        sms_code = redis_conn.get("%s_code" % mobile)
        if not sms_code:
            # 生成新的短信验证码
            sms_code = "%06d" % random.randint(0, 999999)
            # 存储验证码到redis数据库
            redis_conn.set("%s_code" % mobile, sms_code, ex=60 * 5)
        else:
            sms_code = sms_code.decode("utf-8")

        redis_conn.set("%s_flag" % mobile, 1, ex=60)  # 一分钟后自动清除
        # 7.执行异步任务发送验证码
        send_sms_code.delay(mobile, sms_code)
        print(sms_code)

        return Response(data={"messages": "短信验证码发送成功"})
Example #6
0
    def get(self, request, mobile):
        # 1. 创建redis连接对象
        redis_conn = get_redis_connection('verify_codes')
        # 2. 从redits中获取发送标记
        # 60秒内不允许重发发送短信
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        # 3.如果获取到类标记,说明手机号频繁发送短信
        if send_flag:
            return Response({"message": "发送短信过于频繁"},
                            status=status.HTTP_400_BAD_REQUEST)
        # 4. 生成验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 创建redis管道 把多次redis操作装入管道中,将来一次性去执行,减少redis连接操作
        pl = redis_conn.pipeline()
        # 5. 把验证码存储到redis数据库
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 6. 把验证码存储到redis数据库
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 执行管道
        pl.execute()

        # 7. 利用容联云通讯发送短信验证码
        # CCP().send_template_sms(self, 手机号, [验证码,5], 1):
        # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)
        # celery异步发送短信
        send_sms_code.delay(mobile, sms_code)
        # 8. 响应
        return Response({'message': 'ok'})
Example #7
0
    def get(self, request: Request, mobile):
        # 校验图片验证码和发送短信的频次
        # mobile是被放到了类视图对象中,只要不是查询字符串和请求体,都是存放在view的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管道一次执行多个redis命令
        pl = redis_conn.pipeline()
        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()

        # 发送短信(交给celery异步执行耗时任务)
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SMS_CODE_TEMP_ID)

        # 使用celery发布异步任务
        send_sms_code.delay(mobile, sms_code)

        return Response({'message': 'OK'})
Example #8
0
 def get(self, request, mobile):
     # 1.获取前端传递的手机号,路径中进行正则匹配
     # 判断前端发送请求的时间间隔 60s
     # 建立链接redis的对象
     conn = get_redis_connection('sms_code')
     flag = conn.get('sms_code_flag_%s' % mobile)
     if flag:
         return Response({'error': '请求过于频繁'}, status=400)
     # 2.生成短信验证码
     sms_code = '%06d' % randint(0, 999999)
     # 3.保存验证码到缓存中
     # 建立链接redis对象
     conn = get_redis_connection('sms_code')
     # string类型写入
     # setex三个参数,第一个参数是key值,第二个是有效期,第三个是value值
     # 常规用法
     # conn.setex('sms_code_%s'%mobile, 300, sms_code)
     # conn.setex('sms_code_flag_%s' % mobile, 60, 1)
     # 管道用法
     pl = conn.pipeline()
     pl.setex('sms_code_%s' % mobile, 300, sms_code)
     pl.setex('sms_code_flag_%s' % mobile, 60, 1)
     # 连接redis缓存,传入写入指令
     pl.execute()
     # 4.发送短信
     # ccp = CCP()
     # ccp.send_template_sms(mobile, [sms_code, '5'], 1)
     # 使用线程发送短信
     # t = Thread(target='send_sms_code', kwargs={'mobile': mobile, 'sms_code': sms_code})
     # t.start()
     # t.join()
     # 使用celery发送短信
     send_sms_code.delay(mobile, sms_code)
     # 5.结果返回
     return Response({'message': 'ok'})
Example #9
0
    def get(self, request, mobile):
        """
        限制60秒内只能向个一个手机号码发送一次短信验证码

        """
        # 获取Redis的连接: 从配置中的cache处,根据名称获取连接
        redis_cli = get_redis_connection('sms_code')
        # 1.判断60秒内是不是向指定手机号码发过短信,如果发过,则抛异常
        if redis_cli.get('sms_flag_' + mobile):
            raise serializers.ValidationError('您发送短信太过频繁')
        # 2.如果未发短信,则随机生成6位随机数
        code = random.randint(100000, 999999)
        code = 123456
        # 2.1 保存到redis:验证码,发送的标记 优化(使用pipeline管道)
        redis_pipeline = redis_cli.pipeline()
        redis_pipeline.setex('sms_code_' + mobile, constants.SMS_CODE_EXPIRES,
                             code)
        redis_pipeline.setex('sms_flag_' + mobile, constants.SMS_FLAG_EXPIRES,
                             1)
        redis_pipeline.execute()
        # 3.发送短信:云通讯
        # CCP.sendTemplateSMS(mobile, code, constants.SMS_CODE_EXPIRES/60, 1)
        #  调用celery任务,执行耗时代码
        send_sms_code.delay(mobile, code, constants.SMS_CODE_EXPIRES / 60, 1)
        # 4.响应
        return Response({'message': 'ok'})
Example #10
0
    def get(self,request,mobile):
        # 获取redis的链接
        redis_cli = get_redis_connection('sms_code')
        #1.判断60s内是否向手机发过短信
        # 如发过,抛出异常
        if redis_cli.get('sms_flag_'+mobile):
            raise serializers.ValidationError('此手机在60s秒内已发送过验证码')
        #2.如果未发送短信
        #2.1 获取随机的6位数
        code = random.randint(100000,999999)

        #2.2 保存到redis中  验证码  发送的标记
        # redis_cli.setex('sms_code_'+mobile,300,code)
        # redis_cli.setex('sms_flag_' + mobile, 60, 1)
        # 优化:pipeline
        # 减少与redis数据库交互的次数,现在只交互一次,之前交互两次
        redis_pipeline=redis_cli.pipeline()
        redis_pipeline.setex('sms_code_'+mobile,constans.SMS_CODE_EXPIRES,code)
        redis_pipeline.setex('sms_flag_' + mobile, constans.SMS_FLAG_EXPIRES, 1)
        redis_pipeline.execute()

        #2.3 发短信 云通信
        # CCP.sendTemplateSMS(mobile,code,constans.SMS_CODE_EXPIRES/constans.SMS_FLAG_EXPIRES,1)
        # print(code)
        # 调用celery任务,执行耗时代码
        send_sms_code.delay(mobile,code,constans.SMS_CODE_EXPIRES/60,1)
        print(code)
        #3.响应
        return Response({'message':'OK'})
Example #11
0
    def get(self,request,mobile):
        """
         GET /sms_codes/(?P<mobile>1[3-9]\d{9})/
        :param request:
        :param mobile:
        :return:
        """
        # 0.创建redis连接对象
        redis_conn = get_redis_connection('verify_codes')
        # 1.获取此手机号是否有发送过的标记
        flag = redis_conn.get('send_flag_%s' % mobile)
        # 2.如果已发送就提前响应,不执行后续代码
        if flag:  # 如果if成立说明此手机号60秒内发过短信
            return Response({'message': '频繁发送短信'}, status=status.HTTP_400_BAD_REQUEST)

        # 3生成六位随机验证码
        smc_code='%06d' % randint(0,999999)
        logger.info(smc_code)
        # 创建redis的管道命令
        pl = redis_conn.pipeline()

        # 4把短信验证码缓存到redis  setex(key 过期时间, value)
        pl.setex('sms_%s' % mobile,constants.SMS_CODE_REDIS_EXPIRES,smc_code)
        # 4.1 存储此手机号已发送短信标记
        pl.setex('send_flag_%s' % mobile, constants.SMS_CODE_REDIS_SIANS, 1)

        # 执行管道
        pl.execute()
        # 5使用容联云通讯去发送短信  send_template_sms(self, to, datas, temp_id)
        # CCP().send_template_sms( mobile,[smc_code,constants.SMS_CODE_REDIS_EXPIRES // 60],1)

        # 触发异步任务(让发短信不要阻塞主线程)
        send_sms_code.delay(mobile, smc_code)
        # 6响应结果
        return Response({'message':'OK'})
Example #12
0
    def get(self, request, mobile):
        image_code = request.GET.get('image_code')
        image_code_id = request.GET.get('image_code_id')



        if not all([image_code, image_code_id]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})

        redis_conn = get_redis_connection('verify_code')
        redis_str = redis_conn.get('img_%s' % image_code_id)
        redis_flag = redis_conn.get(mobile)
        if redis_str is None:
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码超时'})

        redis_str = redis_str.decode().lower()
        try:
            redis_conn.delete('img_%s' % image_code_id)
        except Exception as e:
            logger.error(e)

        if redis_str != image_code.lower():
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '验证码错误'})

        if redis_flag != None:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '访问过于频繁'})

        rand_int = '%06d' % random.randint(0, 999999)
        logger.info(rand_int)
        redis_conn = get_redis_connection('verify_code').pipeline()
        redis_conn.setex('%s_%s' % (rand_int, mobile), 300, rand_int)
        redis_conn.setex('%s' % mobile, 60, 1)
        redis_conn.execute()
        send_sms_code.delay(mobile,rand_int)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})
Example #13
0
    def get(self, request, mobile):
        # 链接到redis数据库
        redis_conn = get_redis_connection('verify_code')

        # 判断已为当前手机号发送验证码
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        # 如果短信发送标志存在则不产生新验证码
        if send_flag:
            return Response({'message': '频繁发送短信'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 生成六位数字验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 创建数据库管道
        pl = redis_conn.pipeline()

        # 把当前手机号与短信验证码保存到redis数据库
        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().send_template_sms(mobile, [sms_code, constants.YUNTONGXUN_EXPIRES], constants.YUNTONGXUN_TEMPLATE)
        # 通过异步任务发送短信验证码
        send_sms_code.delay(mobile, sms_code)

        # 返回数据
        return Response({'message': '0k'})
Example #14
0
    def get(self, request, mobile):
        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.SMS_SEND_INTERVAL, 1)

        # 使用redis管道代替之前的直接执行命令,可以一次执行多条命令
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        pl.setex("send_flag_%s" % mobile, constants.SMS_SEND_INTERVAL, 1)

        # 让管道执行命令
        pl.execute()

        # 发送短信
        # ccp = CCP()

        # sms_time = str(constants.SMS_CODE_REDIS_EXPIRES / 60)
        # ccp.send_template_sms(mobile, [sms_code, sms_time], constants.SMS_CODE_TEMPLATE_ID)

        # 使用celery异步实现
        send_sms_code.delay(mobile, sms_code)

        return Response({'message': 'ok'})
Example #15
0
    def get(self, request, mobile):

        image_code = request.GET.get('image_code')
        image_code_id = request.GET.get('image_code_id')

        if not all([image_code, image_code_id]):
            return HttpResponseBadRequest('参数不全')

        from django_redis import get_redis_connection

        redis_conn = get_redis_connection('code')

        redis_text = redis_conn.get('img_%s' % image_code_id)

        if redis_text is None:
            return HttpResponseBadRequest('图片验证码已过期')

        if redis_text.decode().lower() != image_code.lower():
            return HttpResponseBadRequest('图片验证码不一致')

        from random import randint
        sms_code = '%06d' % randint(0, 999999)

        redis_conn.setex('sms_%s' % mobile, 300, sms_code)
        # CCP().send_template_sms(mobile,[sms_code,5],1)
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)

        return JsonResponse({'msg': 'ok', 'code': '0'})
Example #16
0
    def get(self, request, mobile):
        # 0.从redis获取发送标记
        redis_conn = get_redis_connection('verify_codes')
        # 如果获取不到,会返回None
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        if send_flag:
            return Response({'message': '手机号频繁发送短信'}, status=status.HTTP_400_BAD_REQUEST)

        # 1.生成随机6位数字,不够补0
        sms_code = '%06d' % randint(0, 999999)

        # 2.创建redis管道,减少redis连接操作
        pl = redis_conn.pipeline()
        # 2.1 存储验证码到redis,300秒过期
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 2.2 存储一个标记,,标识此手机号已发送过短信,有效期60s
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 2.3 执行管道
        pl.execute()

        # 3.调用第三方sdk发送短信
        # CCP().send_template_sms(self, 手机号, [验证码, 过期时间], 模板id)
        # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)  # //表示整除
        send_sms_code.delay(mobile, sms_code)   # 添加异步任务
        logger.info('添加异步任务,发送验证码:{}'.format(sms_code))

        # 4.响应
        return Response({'messsage': 'ok'})
Example #17
0
    def get(self, request):
        access_token = request.GET.get('access_token')

        user_dict = s.loads(access_token)

        if user_dict is None:
            return JsonResponse({}, status=400)

        mobile = user_dict['mobile']

        try:
            User.objects.get(mobile=mobile)

        except:

            return JsonResponse({}, status=400)
        redis_conn = get_redis_connection('code')

        if redis_conn.get('sms_%s' % mobile) is not None:
            return JsonResponse({
                'code': RETCODE.SMSCODERR,
                'errmsg': '发送短信太频繁'
            })

        from random import randint
        sms_code = '%06d' % randint(0, 999999)

        redis_conn.setex('sms_%s' % mobile, 300, sms_code)

        from celery_tasks.sms.tasks import send_sms_code

        send_sms_code.delay(mobile, sms_code)

        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
Example #18
0
    def get(self,request,mobile):

        # 1.接收前端数据
        params = request.query_params

        # 2. 校验数据

        # text = params.get('text')
        # image_code_id = params.get('dd')
        #
        # if not all([text,image_code_id]):
        #     pass
        # 校验
        serializer = RegisterSmscodeSerializer(data=params)
        # 调用 is_valid 才会校验
        serializer.is_valid(raise_exception=True)

        # 3. 先生成短信
        from random import randint
        sms_code = "%06d"%randint(0,999999)
        # 4. 保存短信,发送短信
        redis_conn = get_redis_connection('code')
        redis_conn.setex('sms_%s'%mobile,300,sms_code)

        # CCP().send_template_sms(mobile,[sms_code,5],1)

        from celery_tasks.sms.tasks import send_sms_code
        # delay 的参数和send_sms_code 任务的参数是对应的
        send_sms_code.delay(mobile,sms_code)
        # 5. 返回响应
        return Response({'msg':'OK'})
Example #19
0
    def get(self, request, mobile):
        # 1. 在序列化器中 检查图片验证码
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        # 2. 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)

        # 3. 保存短信验证码与发送记录
        redis_conn = get_redis_connection('verify_codes')
        # 当项目中连续出现多条操作redis的语句时,可以使用pipeline管道命令,把多条操作
        # 组合到一次发送给redis,可以有效提高执行效率
        # 通过pipeline方法,获取管道对象,管道对象继承于redis连接对象
        # 所以redis中本身支持方法属性,pipeline对象也可以操作
        pl = redis_conn.pipeline()
        pl.multi()
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 发送短信的标志,维护60秒
        pl.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        pl.execute()  # 把上面组装的操作一并执行

        # 4. 发送短信
        # ccp = CCP()
        # time = str(constants.SMS_CODE_REDIS_EXPIRES/60)
        # ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_TEMP_ID)

        # 调用celery异步发送短信,异步任务函数中的参数, 必须一一按照顺序填写delay中
        send_sms_code.delay(mobile, sms_code)



        # 5. 返回响应
        return Response({"message": "OK"}, status.HTTP_200_OK)
Example #20
0
    def get(self, request, mobile):
        #与redis建立链接(指定那个数据库)
        redis_cli = get_redis_connection('sms_code')
        ## 1.判断60秒内是不向指定手机号发过短信,如果发过,则抛异常,只需要判断标记存在么
        if redis_cli.get('sms_flag' + mobile):
            raise serializers.ValidationError('向此手机号发短信太频繁了')
        # 2.如果未发短信,则
        # 2.1随机生成6位数
        code = random.randint(100000, 999999)
        print(code)

        # 2.2保存到redis:验证码,发送的标记
        # redis_cli.setex('sms_code_'+mobile,300,code)
        # redis_cli.setex('sms_flag_'+mobile,60,1)
        # 优化:pipeline管道
        radis_pipeline = redis_cli.pipeline()
        radis_pipeline.setex('sms_code' + mobile, constants.SMS_CODE_EXPIRES,
                             code)
        radis_pipeline.setex('sms_flag' + mobile, constants.SMS_FLAG_EXPIRES,
                             1)
        radis_pipeline.execute()

        # 2.3发短信:云通讯
        # CCP.sendTemplateSMS(mobile,code,constants.SMS_CODE_EXPIRES/60,1)
        # print(code)
        # 调用celery任务,执行耗时代码

        send_sms_code.delay(mobile, code, constants.SMS_CODE_EXPIRES / 60, 1)

        return Response({'message': 'OK'})
Example #21
0
    def get(self, request: Request):
        # 获取并校验access_token
        access_token = request.query_params.get('access_token')
        if not access_token:
            return Response({'message': '缺少access_token'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 从access_token中获取手机号
        mobile = User.check_send_sms_code_token(access_token)
        if not mobile:
            return Response({'message': '无效的access_token'},
                            status=status.HTTP_400_BAD_REQUEST)

        # 判断手机号发送频次
        redis_conn = get_redis_connection('verify_codes')
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        if send_flag:
            return Response({'message': '发送短信次数过于频繁'},
                            status=status.HTTP_429_TOO_MANY_REQUESTS)

        # 生成短信验证码
        sms_code = '%06d' % random.randint(0, 999999)

        # 保存并发送短信验证码
        pl = redis_conn.pipeline()
        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()

        send_sms_code.delay(mobile, sms_code)

        return Response({'message': 'OK'})
Example #22
0
    def get(self, request, mobile):
        # 判断图片验证码,短信验证码是否在60s内
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        # 2、校验参数
        # 生成短信验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.debug(sms_code)
        # 存储短信到redis数据库
        # 生成redis管道,将多个redis指令集成到一起执行,减少访问redis数据库次数
        redis_conn = get_redis_connection('verify_codes')
        pl = redis_conn.pipeline()
        pl.setex('sms_' + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 记录发送短信的标记
        pl.setex('send_flag_' + mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 开启执行
        pl.execute()
        # 3、业务处理
        # 发送短信
        # ccp = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES//60], constants.SMS_CODE_TEMP_ID)

        # 执行异步任务:delay将延迟异步任务发送到redis
        send_sms_code.delay(mobile, sms_code)
        # 4、返回结果
        return Response({'message': 'OK'})
Example #23
0
    def get(self, request):
        access_token = request.GET.get('access_token')

        try:
            user_id = pickle.loads(base64.b64decode(access_token.encode()))
            user = User.objects.get(id=user_id)
            mobile = user.mobile
        except:
            return http.HttpResponseForbidden('无效的access_token')

        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)

        redis_conn = get_redis_connection('verify_code')
        # redis管道技术
        pl = redis_conn.pipeline()
        # 将短信验证码存储到redis,以备后期注册时校验
        # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)

        # 向redis多存储一个此手机号已发送过短信的标记,此标记有效期60秒
        # redis_conn.setex('send_flag_%s' % mobile, 60, 1)
        pl.setex('send_flag_%s' % mobile, 60, 1)

        # 执行管道
        pl.execute()

        # 给当前手机号发短信
        # CCP().send_template_sms(要收短信的手机号, [短信验证码, 短信中提示的过期时间单位分钟], 短信模板id)
        # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)
        send_sms_code.delay(mobile, sms_code)  # 生产任务
        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信验证码成功'})
Example #24
0
    def get(self, request, mobile, celery_tasks=None):
        # 2. 对图片验证码和uuid进行校验, 手机号也要校验
        #需要对数据进行验证(反序列化)
        #/(?P<mobile>1[3-9]\d{9})/?text=xxxx&image_code_id=xxxx
        #获取get中的查询字符串的时候需要使用request中的query_params
        data = request.query_params
        #创建序列化器械
        serializer = RegisterSmscodeSerializer(data=data)
        serializer.is_valid()
        #3.需要对手机号发送记录进行判断(60秒之内是否有发送过)
        redis_conn = get_redis_connection('code')
        #获取发送的状态
        if redis_conn.get('sms_flag_%s'%  mobile):
            return Response(status=status.HTTP_429_TOO_MANY_REQUESTS)
        #4.生成短信
        from random import randint
        sms_code = '%06d' % randint(0,999999)
        print('手机验证码为: %s' % sms_code)
        #5.redis记录短信内容后面注册的时候需要验证   60秒以后过期,用的默认的1号模板 key time value\
        # 记录为string
        redis_conn.setex('sms_%s'%mobile,5*60,sms_code)
        # 记录发送状态
        redis_conn.setex('sms_flag_%s' % mobile, 60, 1)
        # 6.发送短信
        # ccp = CCP() # mobile:向谁发 []:发什么, 60:过期时间, 1:模板  ,
        # ccp.send_template_sms(mobile, [sms_code], 60, 1)
        from celery_tasks.sms.tasks import send_sms_code
        # 注意: 异步任务必须使用 delay调用
        # delay的参数是 和 任务的参数是一致的
        # send_sms_code(mobile,sms_code) --错误代码 不能这样发送
        send_sms_code.delay(mobile, sms_code)

        return Response({'message': 'ok'})
Example #25
0
    def get(self,request,mobile):
        #验证码内容的校验(序列化器)
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)
        #判断用户是否已经有发送记录 ,防止用户频繁操作
        redis_conn = get_redis_connection('code')
        if redis_conn.get('sms_flag_%s' % mobile):
            return Response(status=status.HTTP_429_TOO_MANY_REQUESTS)
        #生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        #记录发送状态
        # redis_conn.setex('sms_%s'%mobile,constants.SMS_CODE_EXIPRE_TIME,sms_code)
        #1 表示已经发送
        # redis_conn.setex('sms_flag_%s'%mobile,60,1)
        # 创建管道 将一行代码就执行一次redis操作 变成将管道中 的操作一起发送给redis-server  提高效率
        pl = redis_conn.pipeline()

        # 将我们的指令放到管道中 等待统一执行
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_EXIPRE_TIME, sms_code)
        pl.setex('sms_flag_%s' % mobile, 60, 1)

        # 执行
        pl.execute()
        #发 送
        # ccp = CCP()
        # ccp.send_template_sms(mobile,(sms_code,5),1)
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile,sms_code)
        #由于我们的短信下发是同步操作的,同步操作有可能会出现等待的情况,造成响应不能及时返回
        #我们就直接采用celery  进行短信下发
        return Response({'message':'ok'})
    def get(self, request, mobile):
        # 1.后端接收数据
        query_params = request.query_params

        # 2.校验数据 (数据格式,数据的内容[图片验证码是否正确])
        # text = query_params.get('text')
        # image_code_id=query_params.get('image_code_id')

        serializer = RegisterSmsCodeSerializer(data=query_params)
        serializer.is_valid(raise_exception=True)

        # 3.生成一个短信码
        import random
        sms_code = '%06d' % random.randint(0, 999999)

        # 4.发送短信
        # CCP().send_template_sms(mobile,[sms_code,5],1)

        from celery_tasks.sms.tasks import send_sms_code

        # send_sms_code(mobile,sms_code)  错误的
        # delay 的参数 同前边函数的参数
        send_sms_code.delay(mobile, sms_code)

        # 5.保存短信
        redis_conn = get_redis_connection('code')

        # redis_conn.setex(key,expire,value)
        redis_conn.setex('sms_%s' % mobile, 5 * 60, sms_code)
        # 6.返回相应
        return Response({'msg': 'ok'})
Example #27
0
    def get(self, request, mobile):
        '''
        限制60秒内只向一个手机号发送一次短信验证码
        '''
        # 获取Redis的连接:从配置中的cache处,根据名称获取连接
        redis_cli = get_redis_connection('sms_code')
        # 1.判断60秒内是不向指定手机号发过短信,如果发过,则抛异常
        if redis_cli.get("sms_flag_" + mobile):
            raise serializers.ValidationError('向此手机号发短信太频繁了')
        # 2.如果未发短信,则
        #2.1随机生成六位数
        code = random.randint(100000, 999999)
        # 2.2保存到redis:验证码,发送的标记
        # redis_cli.setex('sms_code_'+mobile,300,code)
        # redis_cli.setex('sms_flag_'+mobile,60,1)
        # 优化:pipeline管道
        redis_pipeline = redis_cli.pipeline()
        redis_pipeline.setex('sms_code_' + mobile, constans.SMS_CODE_EXPIRES,
                             code)
        redis_pipeline.setex('sms_flag_' + mobile, constans.SMS_FLAG_EXPIRES,
                             1)
        redis_pipeline.execute()
        # 2.3发短信:云通讯
        CCP.sendTemplateSMS(mobile, code, constans.SMS_CODE_EXPIRES / 60, 1)
        print(code)
        # 调用celery任务,执行耗时代码
        send_sms_code.delay(mobile, code, constans.SMS_CODE_EXPIRES / 60, 1)

        # 3.响应
        return Response({'message': 'OK'})
Example #28
0
    def get(self, request):
        # 解析token,获取mobile
        access_token = request.GET.get('access_token')
        # 创建token对象
        token = TOKEN(settings.SECRET_KEY, 300)
        mobile = token.loads(access_token)['mobile']
        # 生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        # 创建redis管道对象来用于保存数据,能提高代码运行效率
        redis_conn = get_redis_connection('verify_code')
        pl = redis_conn.pipeline()
        # 保存短信验证码
        pl.setex('sms_%s' % mobile, 60 * 3, sms_code)
        # 手机号发过短信后在redis中存储一个标记
        # redis_conn.setex('send_flag_%s' % mobile, 60, 1)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        # 执行管道
        pl.execute()

        # 发送短信验证码 (后面参数信息为 手机号,[验证码, 有效时间单位分钟], 短信模板ID)
        # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRE // 60], constants.SMS_TEMPLATE_ID)
        # 将需要执行的任务列表存储在broker
        send_sms_code.delay(mobile, sms_code)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '短信发送成功'})
Example #29
0
def sms_codes(request):
    """
    发送短信验证码
    :param request:
    :return:
    """
    mobile = request.GET.get('mobile')
    redis_conn = get_redis_connection('verify_codes')
    send_flag = redis_conn.get('send_flag_%s' % mobile)
    if send_flag:
        return JsonResponse(data={"error": "发送短信过于频繁", "status": 400})
    if not mobile:
        return JsonResponse(data={"error": "缺少必传参数", "status": 400})
    # 判断手机号是否合法
    if not re.match(r'^1[3-9]\d{9}$', mobile):
        return JsonResponse(data={"error": "请输入正确的手机号码", "status": 400})
    # ⽣成短信验证码:⽣成6位数验证码
    sms_code = '%06d' % random.randint(0, 999999)
    # CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)
    # celery异步发送短信
    send_sms_code.delay(mobile, sms_code)
    pl = redis_conn.pipeline()
    # 保存短信验证码
    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()

    return JsonResponse(data={"message": "发送成功", "status": 200})
Example #30
0
 def get(self, request, mobile):
     #创建redis连接对象
     redis_conn = get_redis_connection('verify_codes')  # 指定数据库名称连接到数据库
     # 从redis中获取标记
     send_flag = redis_conn.get('send_flag_%s' % mobile)  # 取不到也不会报错 是none
     if send_flag:  # 如果取到了标记说明此手机号频繁发送
         return Response({'message': '手机频繁发送短信'},
                         status=status.HTTP_400_BAD_REQUEST)
     # 生成验证码
     sms_code = '%06d' % randint(0, 999999)
     logger.info(sms_code)
     # 创建redis管道(把多次redis操作放入管道中将一次性去执行,减少redis连接操作)
     pl = redis_conn.pipeline()
     #.把验证码存储到redis数据库
     # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)  # 键,存储时间秒,值
     pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES,
              sms_code)  # 键,存储时间秒,值
     # 存储一个标记表示此手机号已经发送过短信 标记有效期为60s
     # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)  # 键,存储时间秒,值
     pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL,
              1)  # 键,存储时间秒,值
     # 执行管道
     pl.execute()
     # import time
     # time.sleep(5) #现在是单线程吗 就已经是多任务了吧 服务器自己解决的runserver或者你部署nginx等
     #利用容联云通讯发送短信验证码
     # CCP().send_template_sms(to, datas, temp_id) to是手机号 datas是列表[验证码,5] 5是分钟表示过期时间 还有短信内容的模板
     # CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)
     # 触发异步任务,将异步任务添加到celery任务队列
     send_sms_code(mobile, sms_code)  # 这么做是错的 调用普通函数而已
     send_sms_code.delay(mobile, sms_code)  # 触发异步任务
     #响应
     return Response({'message': 'ok'})