flask项目之5:短信验证码发送

本文介绍了如何利用容联云平台发送短信验证码,强调了在测试时需限制发送频率以节省成本。短信验证码的发送依赖于图片验证码的验证,并通过Python SDK实现。同时,文章展示了如何使用单例模式确保短信发送类的唯一性,以避免资源浪费。在实际业务逻辑中,详细阐述了从接收用户请求到验证图片验证码,再到生成和发送短信验证码的整个流程,确保了安全性与效率。
摘要由CSDN通过智能技术生成
概述:
  • 短信验证码的发送需要限制验证码的发送间隔不能不停的发,因为测试时发送的验证码是要花钱的,不可能不花钱就办事
  • 短信验证码要根据图片验证码是不是正确再进行发,
    进行短信验证码的实验要测试容联云平台;然后将短信验证码的类设置为单例模式(每次实例化都是用的一个地址,不会产生新的类)
  • 1.容联云平台:
  • 2.单例模式
  • 3.验证码相关逻辑与实现位置
    容联云平台测试:
    http://yuntongxun.com/member/main
    在这里插入图片描述
    点击开发文档,可以查看相关的开发文档,
    在这里主要用到的就是短信开发手册
    http://doc.yuntongxun.com/space/5a5098313b8496dd00dcdd7f
    以下为容联云平台的python SDK
    https://doc.yuntongxun.com/p/5f029ae7a80948a1006e776e
    调用示例:
    使用前先要安装ronglian_sms_sdk
pip install ronglian_sms_sdk
from ronglian_sms_sdk import SmsSDK
 
accId = '容联云通讯分配的主账号ID'
accToken = '容联云通讯分配的主账号TOKEN'
appId = '容联云通讯分配的应用ID'
 
def send_message():
    sdk = SmsSDK(accId, accToken, appId)
    tid = '容联云通讯创建的模板ID'
    mobile = '手机号1,手机号2'
    datas = ('变量1', '变量2')
    resp = sdk.sendMessage(tid, mobile, datas)
    print(resp)
说明下,其中的datas对应的是短信模板里的1和2
登录验证模版您的验证码为{1},请于{2}内正确输入,如非本人操作,请忽略此短信。
  • 单例模式:
class CCP(object):
    """发送短信的单例类"""
    # _instance = None

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super().__new__(cls, *args, **kwargs)
            #cls._instance.sdk = SmsSDK(accId, accToken, appId)
        return cls._instance

a = CCP()
print(id(a))
b = CCP()
print(id(b))

通过这样的方式获得的实例共用一个空间
如果采用传统方式,则每个实例占一个空间,实例不再列举

短信验证码发送:
在libs中新建包:ronglianyun,新建ccp_sms.py文件,在其中新建发送模板的单例类

from ronglian_sms_sdk import SmsSDK
import json

accId = '8a216dxxxxxxxxxxxxxx'
accToken = 'xxxxxxxxxxxxxxxx'
appId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'


class CCP(object):
    """发送短信的单例类"""
    # _instance = None

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = super().__new__(cls, *args, **kwargs)
            cls._instance.sdk = SmsSDK(accId, accToken, appId)
        return cls._instance

    def send_message(self, mobile, datas, tid):
        sdk = self._instance.sdk
        resp = sdk.sendMessage(tid, mobile, datas)
        result = json.loads(resp)
        if result['statusCode'] == '000000':
            return 0
        else:
            return -1

然后在蓝图verify_code.py新建路由:

@api.route("/sms_codes/<re(r'1[345678]\d{9}'):mobile>")
def get_sms_code(mobile):
    """获取短信验证码"""
    # 获取参数
    # 图片验证码
    image_code = request.args.get('image_code')
    # UUID
    image_code_id = request.args.get('image_code_id')

    # 校验参数
    if not all([image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 业务逻辑
    # 从redis中取出验证码
    try:
        real_image_code = redis_store.get('image_code_%s' % image_code_id)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='redis数据库异常')

    # 判断图片验证码是否过期
    if real_image_code is None:
        return jsonify(errno=RET.NODATA, errmsg='图片验证码失效')

    # 删除redis中的图片验证码
    try:
        redis_store.delete('image_code_%s' % image_code_id)
    except Exception as e:
        logging.error(e)

    # print(real_image_code)  b'RVMJ'
    # 与用户填写的图片验证码对比
    real_image_code = real_image_code.decode()
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码错误')

    # 判断手机号的操作
    try:
        send_flag = redis_store.get('send_sms_code_%s' % mobile)
    except Exception as e:
        logging.error(e)
    else:
        if send_flag is not None:
            return jsonify(errno=RET.REQERR, errmsg='请求过于频繁')

    # 判断手机号是否存在
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        logging.error(e)
    else:
        if user is not None:
            # 表示手机号已经被注册过
            return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')

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

    # 保存真实的短信验证码到redis
    try:
        # redis管道
        pl = redis_store.pipeline()
        pl.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 保存发送给这个手机号的记录
        pl.setex('send_sms_code_%s' % mobile, constants.SNED_SMS_CODE_EXPIRES, 1)
        pl.execute()

    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存短信验证码异常')


    # 发短信
    try:
        ccp = CCP()
        result = ccp.send_message(mobile, (sms_code, int(constants.SMS_CODE_REDIS_EXPIRES/60)), 1)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送异常')

    # 返回值
    if result == 0:
        return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值