Example #1
0
    def get(self, request):

        access_token = request.query_params.get("access_token")
        if not access_token:
            return Response({"message": "缺少access_token"}, status=status.HTTP_400_BAD_REQUEST)
        mobile = User.check_sms_access_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("sms_flag_%s" % mobile)
        if send_flag:
            return Response({"message": "发送短信验证码过于频繁"}, status=status.HTTP_429_TOO_MANY_REQUESTS)

        # 生成验证码并发送
        sms_code = '%06d' % random.randint(0, 999999)
        pipeline = redis_conn.pipeline()
        # 收集命令
        pipeline.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRE, sms_code)
        pipeline.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 提交执行
        pipeline.execute()
        # 使用Redis的pipeline管道,一次处理多e个命令
        # ccp = CCP()
        # time = str(constants.SMS_CODE_REDIS_EXPIRE / 60)
        # ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_CODE_TEMPLATE_ID)

        code = redis_conn.get('sms_%s' % mobile).decode()
        print("{}手机号验证码:{}".format(mobile, code))
        send_sms.delay(mobile, sms_code)
        return Response({"message": "ok"})
Example #2
0
    def get(self, request, mobile):
        # 接收
        image_code_request = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')

        # 验证
        # 1.图片验证码是否正确
        # 1.1读取redis中的图片验证码
        redis_cli = get_redis_connection('verify_code')
        image_code_redis = redis_cli.get(uuid)
        # 1.2判断是否过期
        if image_code_redis is None:
            return http.JsonResponse({
                'code': RETCODE.IMAGECODEERR,
                'errmsg': '图片验证码已经过期'
            })
        # 1.3对比
        # 注意1:在redis读取的数据,都是bytes类型
        # 注意2:不区分大小写
        if image_code_redis.decode() != image_code_request.upper():
            return http.JsonResponse({
                'code': RETCODE.IMAGECODEERR,
                'errmsg': '图片验证码错误'
            })
        # 1.4强制图片验证码过期
        redis_cli.delete(uuid)

        # 2.在60秒内只向指定手机号发一次短信
        if redis_cli.get('sms_flag_' + mobile):
            return http.JsonResponse({
                'code': RETCODE.SMSCODERR,
                'errmsg': '发送短信太频繁'
            })

        # 处理
        # 1.生成6位随机数
        sms_code = '%06d' % random.randint(0, 999999)

        # # 2.保存到redis中
        # redis_cli.setex('sms_' + mobile, constants.SMS_CODE_EXPIRES, sms_code)
        # # 是否在60秒内发送短信的标记
        # redis_cli.setex('sms_flag_' + mobile, constants.SMS_CODE_FLAG_EXPIRES, 1)

        # 优化redis:只与redis服务器交互一次
        redis_pl = redis_cli.pipeline()
        redis_pl.setex('sms_' + mobile, constants.SMS_CODE_EXPIRES, sms_code)
        redis_pl.setex('sms_flag_' + mobile, constants.SMS_CODE_FLAG_EXPIRES,
                       1)
        redis_pl.execute()

        # 3.发短信
        # time.sleep(5)
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRES / 60], 1)
        # print(sms_code)
        # 调用任务
        send_sms.delay(mobile, [sms_code, constants.SMS_CODE_EXPIRES / 60], 1)

        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "OK"})
Example #3
0
    def get(self, request, mobile):
        strict_redis = get_redis_connection('sms_codes')  # type:StrictRedis

        # 校验短信验证码是否重复发送(1分钟内禁止重复发送)
        send_flag = strict_redis.get('send_flag_%s' % mobile)
        if send_flag:
            raise ValidationError({'message': '频繁获取短信验证码'})

        # 生成短信验证码(云通讯)
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info('短信验证码:%s %s' % (mobile.sms_code))

        # # 2. 发送短信验证码(云通讯)
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # sleep(5)
        # 使用celery来发送短信, 可以解决阻塞问题
        send_sms.delay('13600000000', '123456')

        # 使用管道优化代码
        pipeline = strict_redis.pipeline()
        pipeline.setex('sms_%s' % mobile, 60 * 5, sms_code)
        pipeline.setex('send_flag_%s' % mobile, 60, 1)
        result = pipeline.execute()  # 管道列表
        print(result)

        # 响应数据
        return Response({'message': 'OK'})
Example #4
0
    def get(self, request, mobile):
        strict_redis = get_redis_connection('sms_codes')

        # 60秒内禁止重复发送短信验证码
        send_flag = strict_redis.get('send_flag_%s' % mobile)

        if send_flag:
            return Response({'message': '发送短信过于频繁'})

        # 生成短信验证码
        import random
        sms_code = '%06d' % random.randint(0, 999999)
        loggers.info('sms_code:%s' % sms_code)
        # 使用云通讯发送短信验证码
        # result = CCP().send_template_sms(mobile,[sms_code,5],1)
        # print(result)
        print("验证码:", sms_code)
        # 保存短信验证码到redis expiry
        # strict_redis.setex('sms_%s' % mobile,5*60,sms_code) # 有效期5分钟
        # strict_redis.setex('send_flag_%s' % mobile,60,1)

        # 使用selery发送短信验证码
        send_sms.delay(mobile, sms_code)

        # 获取pipeline对象
        pipeline = strict_redis.pipeline()
        pipeline.setex('sms_%s' % mobile, 5 * 60, sms_code)  # 有效期5分钟
        pipeline.setex('send_flag_%s' % mobile, 60, 1)
        pipeline.execute()  #一次性执行多个命令
        return Response({'message': 'ok'})
Example #5
0
    def get(self, request, mobile):
        """发送短信"""
        # 1. 验证手机号是否已经注册过
        try:
            User.objects.get(mobile=mobile)
            return Response({"message": "对不起,当前手机号已经被注册"},
                            status=status.HTTP_400_BAD_REQUEST)
        except User.DoesNotExist:
            # 如果手机号不存在于数据库,则表示没有注册,不进行任何处理
            pass

        # 2. 验证短信的发送间隔时间[60s]
        # 2.1 链接redis
        redis = get_redis_connection("sms_code")

        # 使用get获取指定键的值,如果获取不到,则返回None
        interval = redis.get("exp_%s" % mobile)
        if interval:
            return Response({"message": "对不起,短信发送间隔太短!"},
                            status=status.HTTP_403_FORBIDDEN)

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

        # 3.2 保存发送的验证码到redis中[手机号码、短信验证码、短信发送间隔、短信有效期]

        # 3.3 调用sdk发送短信
        # 没有使用异步任务框架celery之前的代码
        # ccp = CCP()
        # result = ccp.send_template_sms(mobile, [sms_code, settings.SMS_EXPIRE_TIME//60 ], settings.SMS_TEIMPLATE_ID)

        # 使用异步任务框架celery之后的代码:
        from celery_tasks.sms.tasks import send_sms
        send_sms.delay(mobile, sms_code)

        # 4. 返回发送短信的结果
        # if result == -1:
        #     return Response({"message":"短信发送失败!"},status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        # else:
        """
        字符串
            setex sms_手机号 300 短信验证码
            setex exp_手机号 60  _
        """
        # 事务操作[pipeline是一个管道对象]
        pipe = redis.pipeline()
        pipe.multi()  # 开启事务
        redis.setex("sms_%s" % mobile, settings.SMS_EXPIRE_TIME, sms_code)
        redis.setex("exp_%s" % mobile, settings.SMS_INTERVAL_TIME, "_")
        pipe.excute()  # 执行事务

        return Response({"message": "短信发送成功!"}, status=status.HTTP_200_OK)
Example #6
0
 def get(self, request, mobile):
     # 接受uuid
     uuid = request.GET.get('image_code_id')
     image_code = request.GET.get('image_code')
     # 验证 是否存在六十秒
     redis_cli = get_redis_connection('sms_code')
     if redis_cli.get(mobile + '_flag') is not None:
         return http.JsonResponse({
             'code': RETCODE.SMSCODERR,
             'errmsg': '发送短信太频繁。。'
         })
     if not all([uuid, image_code]):
         return http.JsonResponse({
             'code': RETCODE.PARAMERR,
             'errmsg': '参数不完整'
         })
     # 图形验证码是否正确
     redis_cli = get_redis_connection('image_code')
     image_code_redis = redis_cli.get(uuid)
     if image_code_redis is None:
         return http.JsonResponse({
             'code': RETCODE.IMAGECODEERR,
             'errmsg': '图形验证码失效,点击更换一个'
         })
     # 删除图形验证码 表示不能使用第二次
     redis_cli.delete(uuid)
     if image_code_redis.decode().lower() != image_code.lower():
         return http.JsonResponse({
             'code': RETCODE.IMAGECODEERR,
             'errmsg': '图形验证码错误'
         })
     # 生成随机数
     sms_code = "%06d" % random.randint(0, 999999)
     # redis_cli.setex(mobile, constans.SMS_CODE_EXPIRES, sms_code)
     # # 写发标志防止 重复刷新
     # redis_cli.setex(mobile + '_flag', constans.SMS_CODE_FLAG, 1)
     # 发短信
     redis_cli = get_redis_connection('sms_code')
     redis_pl = redis_cli.pipeline()
     # 存入验证码
     redis_pl.setex(mobile, constans.SMS_CODE_EXPIRES, sms_code)
     # 存入标识符防止刷新
     redis_pl.setex(mobile + '_flag', constans.SMS_CODE_FLAG, 1)
     # 一次提供两行 减少于redis的交互
     redis_pl.execute()
     # 使用管道技术节省空间
     # ccp=CCP()
     # ccp.send_template_sms(mobile, [sms_code,constans.SMS_CODE_EXPIRES/60],1)
     # 通过delay调用,可以将任务加到队列中,交给celery去执行
     send_sms.delay(mobile, sms_code)
     print(sms_code)
     return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})
Example #7
0
    def get(self, request, mobile):
        # 接收
        uuid = request.GET.get('image_code_id')
        image_code = request.GET.get('image_code')

        # 验证
        redis_cli = get_redis_connection('sms_code')

        # 0.是否60秒内
        if redis_cli.get(mobile + '_flag') is not None:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '发送短信太频繁,请稍候再发'})
        # 1.非空
        if not all([uuid, image_code]):
            return http.JsonResponse({"code": RETCODE.PARAMERR, 'errmsg': '参数不完整'})
        # 2.图形验证码是否正确
        # 2.1从redis中读取之前保存的图形验证码文本
        redis_cli = get_redis_connection('image_code')
        image_code_redis = redis_cli.get(uuid)
        # 2.2如果redis中的数据过期则提示
        if image_code_redis is None:
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码已过期,点击图片换一个'})
        # 2.3立即删除redis中图形验证码,表示这个值不能使用第二次
        redis_cli.delete(uuid)
        # 2.3对比图形验证码:不区分大小写
        if image_code_redis.decode().lower() != image_code.lower():
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码错误'})

        # 处理
        # 1.生成随机6位数
        sms_code = '%06d' % random.randint(0, 999999)
        # # 2.1存入redis
        # redis_cli.setex(mobile, constants.SMS_CODE_EXPIRES, sms_code)
        # # 2.2写发送标记
        # redis_cli.setex(mobile + '_flag', constants.SMS_CODE_FLAG, 1)
        # 优化:使用管道
        redis_pl = redis_cli.pipeline()
        redis_pl.setex(mobile, constants.SMS_CODE_EXPIRES, sms_code)
        redis_pl.setex(mobile + '_flag', constants.SMS_CODE_FLAG, 1)
        redis_pl.execute()

        # 3.发短信
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRES / 60], 1)
        # print(sms_code)
        # 通过delay调用,可以将任务加到队列中,交给celery去执行
        send_sms.delay(mobile, sms_code)

        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
Example #8
0
    def get(self, request, mobile):
        # 获取StrictRedis保存数据
        strict_redis = get_redis_connection("sms_codes")  #type: StrictRedis
        # 4. 60秒之内禁止重复发送验证码
        sms_flag = strict_redis.get("sms_flag_%s" % mobile)
        if sms_flag:
            return Response({"message": "发送短信过于频繁"}, status=400)

        # 1.生成短信验证码
        import random
        sms_code = "%06d" % random.randint(0, 999999)
        logger.info('sms_code: %s' % sms_code)
        # 2.使用云通讯发送短信
        # CCP().send_template_sms(mobile, [sms, 5], 1)
        # sleep(5)
        # 使用celery发送耗时验证码
        send_sms.delay(mobile, sms_code)
        print(sms_code)
        # 3.保存短信验证码到redis中
        strict_redis.setex("sms_%s" % mobile, 5 * 60, sms_code)
        strict_redis.setex("sms_flag_%s" % mobile, 60, 1)

        return Response({"message": "OK"})
Example #9
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_EXPIRE, sms_code)
        # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 获取管道
        pipeline = redis_conn.pipeline()
        # 收集命令
        pipeline.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRE, sms_code)
        pipeline.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 提交执行
        pipeline.execute()
        # 使用Redis的pipeline管道,一次处理多e个命令
        # ccp = CCP()
        # time = str(constants.SMS_CODE_REDIS_EXPIRE / 60)
        # ccp.send_template_sms(mobile, [sms_code, time], constants.SMS_CODE_TEMPLATE_ID)

        code = redis_conn.get('sms_%s' % mobile).decode()
        print("{}手机号验证码:{}".format(mobile, code))
        send_sms.delay(mobile, sms_code)
        return Response({"message": "ok"})