美多商城项目之短信验证码

Posted chao666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了美多商城项目之短信验证码相关的知识,希望对你有一定的参考价值。

目前市面上可以发送短信验证码的平台有很多,此项目中使用的容联云通讯进行短信验证码的发送。

首先,我们先来进行手机验证码的逻辑分析,

技术图片

 

通过这张图片,我们基本确定了发送短信验证码的基本逻辑,并且在业务逻辑中,我们不能让短信验证码任务阻塞了响应结果,所以我们需要采用celery方式进行异步发送短信验证码且不会阻塞响应。

容联云通讯网址:https://www.yuntongxun.com/

既然确定了,核心逻辑和解决方案,那么接下来我们就进行代码实现了。

1.模板短信SDK下载

https://www.yuntongxun.com/doc/ready/demo/1_4_1_2.html

2.模板短信SDK使用说明

http://doc.yuntongxun.com/p/5a533e0c3b8496dd00dce08c

1. 定义相关视图

# 编写短信验证码视图
class SmsVerVerifications(View):
    def get(self, request, mobile):
        pass

2. 配置相关路由

url(r^sms_codes/(?P<mobile>1[3-9]d{9})/$,views.SmsVerVerifications.as_view(),name=SMS)

3. 创建celery程序

在项目中,创建一个celery包。

注意:

  celery是一个独立程序,他不属于Django程序。

4. 编写celery程序入口

# celery启动文件
from celery import Celery


# 为celery使用django配置文件进行设置
import os
if not os.getenv(DJANGO_SETTINGS_MODULE):
    os.environ[DJANGO_SETTINGS_MODULE] = meiduo_mall.settings.dev

# 创建celery实例
celery_app = Celery(meiduo)

# 加载celery配置
celery_app.config_from_object(celery_tasks.config)

# 自动注册celery任务
celery_app.autodiscover_tasks([celery_tasks.sms_task])

5. 编写celery程序配置文件

# 指定消息队列的位置
broker_url = "redis://127.0.0.1/10"

注意:

  celery程序遵守的是生产者消费者设计模式,这种设计模式需要一个队列容器来保存任务。

举个例子:

  生产者就相当于LOL官方,

  而这个容器就相当于LOL的道具城,

  消费者就相当于我们玩家,

生产者生产任务,然后放到队列容器中,也就相当于LOL出了个新皮肤,并且上架到了LOL道具城;

消费者从队列容器获取任务并完成任务,就相当于我们玩家发现新出了的皮肤,然后买了这么个过程。

6. 创建celery任务

# 定义任务的文件,文件名必须叫tasks.py
# celery的任务就是函数
from celery_tasks.sms_task.yuntongxun.ccp_sms import sendTemplateSMS
from celery_tasks.sms_task import constants
from celery_tasks.main import celery_app


@celery_app.task(name=ccp_send_sms_code) # name是任务的别名,可以通过name参数自定义任务名字
def ccp_send_sms_code(mobile, sms_code):
    """
    发送短信验证码的异步任务
    :param mobile: 手机号
    :param sms_code: 短信验证码
    :return: None
    """
    sendTemplateSMS(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)

注意:

  celery任务的文件名字必须是tasks.py

想要完成发送短信验证码的任务,在调用之前我们还需要配置容联云通讯的配置文件。

找到容联云配置文件,并修改以下配置项。

# 说明:主账号,登陆云通讯网站后,可在"控制台-应用"中看到开发者主账号ACCOUNT SID
_accountSid = 你的账号ACCOUNT SID

# 说明:主账号Token,登陆云通讯网站后,可在控制台-应用中看到开发者主账号AUTH TOKEN
_accountToken = 你的账号AUTH TOKEN

# 请使用管理控制台首页的APPID或自己创建应用的APPID
_appId = 你的APPID

7. 启动celery并且调用celery任务完成,异步发送短信验证码。

# 使用celery完成异步发送短信验证码
ccp_send_sms_code.delay(mobile, sms_code)

注意:

  celery任务必须使用.delay方法调用,否则无法调用celery任务。

整体代码如下:

from . import constants
from meiduo_mall.utils.response_code import RETCODE
from celery_tasks.sms_task.tasks import ccp_send_sms_code

# 创建日志输出器
logger = logging.getLogger(django)

# 编写短信验证码视图
class SmsVerVerifications(View):
    def get(self, request, mobile):
        redis_conn = get_redis_connection(verify_code)

        # 获取手机验证码标记
        send_flag = redis_conn.get(send_flag_%s % mobile)
        # 判断标记是否存在,存在则发送频繁
        if send_flag:
            return http.JsonResponse({code:RETCODE.THROTTLINGERR,errmsg:验证发送过与频繁})

        # 接收参数
        image_code_client = request.GET.get(image_code)
        uuid = request.GET.get(uuid)

        # 校验参数
        # 创建redis链接,并提取image_code_server
        # redis_conn = get_redis_connection(‘verify_code‘)
        image_code_server = redis_conn.get(img_%s % uuid)

        # 判断图形验证码是否过期
        if not image_code_server:
            return http.JsonResponse({code:RETCODE.IMAGECODEERR,errmsg:图形验证码失效})

        # 删除图形验证码
        redis_conn.delete(img_%s % uuid)

        # 实现核心逻辑
        # 对比图形验证码
        if image_code_client.lower() != image_code_server.decode().lower():
            return http.JsonResponse({code:RETCODE.IMAGECODEERR,errmsg:图形验证码错误})

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

        # 保存短信验证码并设置有效期
        # 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,‘send_flag‘)

        # 优化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, send_flag)
        # 执行命令
        pl.execute()

        # 发送短信验证码
        # sendTemplateSMS(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES // 60],constants.SEND_SMS_TEMPLATE_ID)

        # 使用celery完成异步发送短信验证码
        ccp_send_sms_code.delay(mobile, sms_code)

        # 返回相应结果
        return http.JsonResponse({code:RETCODE.OK,errmsg:发送短信验证码成功})

以上是关于美多商城项目之短信验证码的主要内容,如果未能解决你的问题,请参考以下文章

美多商城项目总结

Python实战美多商城项目:关于性能优化

美多商城项目之用户中心:基本信息邮箱验证收货地址

2018-8-6对美多商城项目的总结

短信验证码之验证码回显

美多商城项目之用户登录页面后端实现