【Django开发】前后端分离django美多商城项目第5篇:短信验证码,避免频繁发送短信验证码【附代码文档】

举报
程序员一诺python 发表于 2025/08/01 18:21:52 2025/08/01
【摘要】 收货地址 省市区三级联动 1. 展示收货地址界面 2. 准备省市区模型和数据 4. Vue渲染省市区数据 新增地址前后端逻辑 1. 定义用户地址模型类 2. 新增地址接口设计和定义 设置默认地址 2. 设置默认地址后端逻辑实现 修改地址标题 3. 修改地址标题前端逻辑实现 修改密码 1. 修改密码后端逻辑 用户中心 商品数据库表设计 SPU和SKU 1. SPU介绍 思考 首页

教程总体简介:收货地址、省市区三级联动、新增地址前后端逻辑、修改地址前后端逻辑、删除地址前后端逻辑、设置默认地址、修改地址标题、修改密码、用户中心、商品数据库表设计、SPU和SKU、首页广告数据库表分析、商品信息数据库表分析、准备商品数据、容器化方案Docker、首页广告、展示首页商品频道分类、自定义Django文件存储类、商品列表页分析、商品列表页、列表页面包屑导航、列表页分页和排序、商品搜索、Haystack扩展建立索引、渲染商品搜索结果、商品详情页分析和准备、展示详情页数据、商品详情页、统计分类商品访问量、设计浏览记录存储方案、保存和查询浏览记录、购物车管理、添加购物车、展示购物车、欢迎来到美多商城!、项目需求分析、项目架构设计、项目介绍、创建工程、配置开发环境、配置Jinja2模板引擎、配置MySQL数据库、配置Redis数据库、修改购物车、合并购物车、展示商品页面简单购物车、创建订单数据库表、保存订单基本信息和订单商品信息、使用事务保存订单数据、提交订单、使用乐观锁并发下单、订单、支付宝介绍、对接支付宝系统、订单支付功能、保存订单支付结果、页面静态化、首页广告页面静态化、商品详情页面静态化、从机端口号、关闭日志、从机唯一编号、开启日志、主机唯一编号、二进制日志文件、1. 收集主机原有数据、2. 从机复制主机原有数据、登录到主机、创建从机账号、刷新权限、登录到从机、从机连接到主机、开启从机服务、展示从机服务状态、配置工程日志、配置前端静态文件、工程创建和配置、项目准备、展示用户注册页面、创建用户模块子应用、追加导包路径、定义用户模型类、用户注册业务实现、用户注册前端逻辑、判断参数是否齐全、判断用户名是否是5-20个字符、判断密码是否是8-20个数字、判断两次密码是否一致

项目完整code和文档,小伙伴们---->git仓库


全套教程部分目录:

短信验证码

避免频繁发送短信验证码

存在的问题:

  • 虽然我们在前端界面做了60秒倒计时功能。
  • 但是恶意用户可以绕过前端界面向后端频繁请求短信验证码。

解决办法:

  • 在后端也要限制用户请求短信验证码的频率。60秒内只允许一次请求短信验证码。
  • 在Redis数据库中缓存一个数值,有效期设置为60秒。

1. 避免频繁发送短信验证码逻辑分析

2. 避免频繁发送短信验证码逻辑实现

1.提取、校验send_flag

send_flag = redis_conn.get('send_flag_%s' % mobile)
if send_flag:
    return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信过于频繁'})

2.重新写入send_flag

# 保存短信验证码


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


# 重新写入send_flag


redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

3.界面渲染频繁发送短信提示信息

if (response.data.code == '4001') {
    this.error_image_code_message = response.data.errmsg;
    this.error_image_code = true;
} else { // 4002
    this.error_sms_code_message = response.data.errmsg;
    this.error_sms_code = true;
}

pipeline操作Redis数据库

Redis的 C - S 架构:

  • 基于客户端-服务端模型以及请求/响应协议的TCP服务。
  • 客户端向服务端发送一个查询请求,并监听Socket返回。
  • 通常是以阻塞模式,等待服务端响应。
  • 服务端处理命令,并将结果返回给客户端。

存在的问题:

  • 如果Redis服务端需要同时处理多个请求,加上网络延迟,那么服务端利用率不高,效率降低。

解决的办法:

  • 管道pipeline

1. pipeline的介绍

管道pipeline

  • 可以一次性发送多条命令并在执行完后一次性将结果返回。
  • pipeline通过减少客户端与Redis的通信次数来实现降低往返延时时间。

实现的原理

  • 实现的原理是队列。
  • Client可以将三个命令放到一个tcp报文一起发送。
  • Server则可以将三条命令的处理结果放到一个tcp报文返回。
  • 队列是先进先出,这样就保证数据的顺序性。

2. pipeline操作Redis数据库

1.实现步骤

1. 创建Redis管道
2. 将Redis请求添加到队列
3. 执行请求

2.代码实现

# 创建Redis管道


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()

短信验证码

生产者消费者设计模式

思考:

  • 下面两行代码存在什么问题?

问题:

  • 我们的代码是自上而下同步执行的。
  • 发送短信是耗时的操作。如果短信被阻塞住,用户响应将会延迟。
  • 响应延迟会造成用户界面的倒计时延迟。

解决:

  • 异步发送短信
  • 发送短信和响应分开执行,将发送短信从主业务中解耦出来。

思考:

  • 如何将发送短信从主业务中解耦出来。

生产者消费者设计模式介绍

  • 为了将发送短信从主业务中解耦出来,我们引入生产者消费者设计模式
  • 它是最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联

总结:

  • 生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
  • 由美多商城生成发送短信消息,缓存到消息队列中,消费者读取消息队列中的发送短信消息并执行。

RabbitMQ介绍和使用

1. RabbitMQ介绍

  • 消息队列是消息在传输的过程中保存消息的容器
  • 现在主流消息队列有:RabbitMQActiveMQKafka等等。

  • RabbitMQActiveMQ比较

    • 系统吞吐量:RabbitMQ好于ActiveMQ
    • 持久化消息:RabbitMQActiveMQ都支持
    • 高并发和可靠性:RabbitMQ好于ActiveMQ
  • RabbitMQKafka

    • 系统吞吐量:RabbitMQ弱于Kafka
    • 可靠性和稳定性:RabbitMQ好于Kafka比较
    • 设计初衷:Kafka是处理日志的,是日志系统,所以并没有具备一个成熟MQ应该具备的特性。
  • 综合考虑,本项目选择RabbitMQ作为消息队列。

2. 安装RabbitMQ(ubuntu 16.04)

1.安装Erlang

  • 由于 RabbitMQ 是采用 Erlang 编写的,所以需要安装 Erlang 语言库。
# 1. 在系统中加入 erlang apt 仓库


$ wget 
$ sudo dpkg -i erlang-solutions_1.0_all.deb



# 2. 修改 Erlang 镜像地址,默认的下载速度特别慢


$ vim /etc/apt/sources.list.d/erlang-solutions.list


# 替换默认值


$ deb  xenial contrib



# 3. 更新 apt 仓库和安装 Erlang


$ sudo apt-get update
$ sudo apt-get install erlang erlang-nox

2.安装RabbitMQ

  • 安装成功后,默认就是启动状态。
# 1. 先在系统中加入 rabbitmq apt 仓库,再加入 rabbitmq signing key


$ echo 'deb  testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list
$ wget -O-  | sudo apt-key add -



# 2. 更新 apt 仓库和安装 RabbitMQ


$ sudo apt-get update
$ sudo apt-get install rabbitmq-server
# 重启


$ sudo systemctl restart rabbitmq-server


# 启动


$ sudo systemctl start rabbitmq-server


# 关闭


$ sudo systemctl stop rabbitmq-server

3.Python访问RabbitMQ

  • RabbitMQ提供默认的administrator账户。
  • 用户名和密码:guestguest
  • 协议:amqp
  • 地址:localhost
  • 端口:5672
  • 查看队列中的消息:sudo rabbitctl list_queues
# Python3虚拟环境下,安装pika


$ pip install pika
# 生产者代码:rabbitmq_producer.py


import pika




# 链接到RabbitMQ服务器


credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))


#创建频道


channel = connection.channel()


# 声明消息队列


channel.queue_declare(queue='zxc')


# routing_key是队列名 body是要插入的内容


channel.basic_publish(exchange='', routing_key='zxc', body='Hello RabbitMQ!')
print("开始向 'zxc' 队列中发布消息 'Hello RabbitMQ!'")


# 关闭链接


connection.close()
# 消费者代码:rabbitmq_customer.py 


import pika




# 链接到rabbitmq服务器


credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))


# 创建频道,声明消息队列


channel = connection.channel()
channel.queue_declare(queue='zxc')


# 定义接受消息的回调函数


def callback(ch, method, properties, body):
    print(body)


# 告诉RabbitMQ使用callback来接收信息


channel.basic_consume(callback, queue='zxc', no_ack=True)


# 开始接收信息


channel.start_consuming()

3. 新建administrator用户

```bash

新建用户,并设置密码

$ sudo rabbitmqctl add_user admin your_password

设置标签为administrator

$ sudo r

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。