【Django开发】0到1美多商城项目md教程第4篇:图形验证码,1. 图形验证码接口设计【附代码文档】
美多商城完整教程(附代码资料)主要内容讲述:欢迎来到美多商城!,项目准备。展示用户注册页面,创建用户模块子应用。用户注册业务实现,用户注册前端逻辑。图形验证码,图形验证码接口设计和定义。短信验证码,避免频繁发送短信验证码。账号登录,用户名登录。登录,登录开发文档。用户基本信息,查询并渲染用户基本信息。收货地址,省市区三级联动。收货地址,展示地址前后端逻辑。商品数据库表设计,SPU和SKU。准备商品数据,容器化方案Docker。首页广告,展示首页商品频道分类。商品列表页,列表页面包屑导航。商品搜索,Haystack扩展建立索引。商品详情页,统计分类商品访问量。购物车管理,添加购物车。购物车管理,删除购物车。订单,结算订单。提交订单,使用乐观锁并发下单。对接系统,订单支付功能。页面静态化,首页广告页面静态化。MySQL读写分离,MySQL主从同步。
全套笔记资料代码移步: 前往gitee仓库查看
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
全套教程部分目录:
部分文件图片:
图形验证码
图形验证码接口设计和定义
1. 图形验证码接口设计
1.请求方式
选项 | 方案 |
---|---|
请求方法 | GET |
请求地址 | image_codes/(?P[\w-]+)/ |
> | |
2.请求参数:路径参数 |
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
uuid | string | 是 | 唯一编号 |
> | |||
3.响应结果:image/jpg |
2. 图形验证码接口定义
1.图形验证码视图
class ImageCodeView(View):"""图形验证码"""def get(self, request, uuid):""":param request: 请求对象:param uuid: 唯一标识图形验证码所属于的用户:return: image/jpg"""pass
2.总路由
# verificationsurl(r'^', include('verifications.urls')),
3.子路由
# 图形验证码url(r'^image_codes/(?P<uuid>[\w-]+)/$', views.ImageCodeView.as_view()),
图形验证码后端逻辑
1. 准备captcha扩展包
提示:
captcha
扩展包用于后端生成图形验证码
可能出现的错误
- 报错原因:环境中没有Python处理图片的库:PIL
解决办法
- 安装Python处理图片的库:
pip install Pillow
2. 准备Redis数据库
准备Redis的2号库存储验证码数据
"verify_code": { # 验证码"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/2","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}},
3. 图形验证码后端逻辑实现
class ImageCodeView(View):"""图形验证码"""def get(self, request, uuid):""":param request: 请求对象:param uuid: 唯一标识图形验证码所属于的用户:return: image/jpg"""# 生成图片验证码text, image = captcha.generate_captcha()# 保存图片验证码redis_conn = get_redis_connection('verify_code')redis_conn.setex('img_%s' % uuid, constants.IMAGE_CODE_REDIS_EXPIRES, text)# 响应图片验证码return http.HttpResponse(image, content_type='image/jpg')
图形验证码前端逻辑
1. Vue实现图形验证码展示
1.register.js
mounted(){// 生成图形验证码this.generate_image_code();
},
methods: {// 生成图形验证码generate_image_code(){// 生成UUID。generateUUID() : 封装在common.js文件中,需要提前引入this.uuid = generateUUID();// 拼接图形验证码请求地址this.image_code_url = "/image_codes/" + this.uuid + "/";},......
}
2.register.html
<li><label>图形验证码:</label><input type="text" name="image_code" id="pic_code" class="msg_input"><img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code"><span class="error_tip">请填写图形验证码</span>
</li>
3.图形验证码展示和存储效果
2. Vue实现图形验证码校验
1.register.html
<li><label>图形验证码:</label><input type="text" v-model="image_code" @blur="check_image_code" name="image_code" id="pic_code" class="msg_input"><img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code"><span class="error_tip" v-show="error_image_code">[[ error_image_code_message ]]</span>
</li>
2.register.js
check_image_code(){if(!this.image_code) {this.error_image_code_message = '请填写图片验证码';this.error_image_code = true;} else {this.error_image_code = false;}
},
3.图形验证码校验效果
短信验证码
短信验证码逻辑分析
知识要点
- 保存短信验证码是为注册做准备的。
- 为了避免用户使用图形验证码恶意测试,后端提取了图形验证码后,立即删除图形验证码。
- Django不具备发送短信的功能,所以我们借助第三方的容联云通讯短信平台来帮助我们发送短信验证码。
容联云通讯短信平台
1. 容联云通讯短信平台介绍
1.容联云官网
- 容联云通讯网址:[
- 注册并登陆
2.容联云管理控制台
3.容联云创建应用
4.应用申请上线,并进行资质认证
5.完成资质认证,应用成功上线
6.添加测试号码
7.短信模板
2. 容联云通讯短信SDK测试
1.模板短信SDK下载
-
[
2.模板短信SDK使用说明
-
[
3.集成模板短信SDK
-
CCPRestSDK.py
:由容联云通讯开发者编写的官方SDK文件,包括发送模板短信的方法 ccp_sms.py
:调用发送模板短信的方法
4.模板短信SDK测试
ccp_sms.py
文件中
# -*- coding:utf-8 -*-from verifications.libs.yuntongxun.CCPRestSDK import REST# 说明:主账号,登陆云通讯网站后,可在"控制台-应用"中看到开发者主账号ACCOUNT SID_accountSid = '8aaf070862181ad5016236f3bcc811d5'# 说明:主账号Token,登陆云通讯网站后,可在控制台-应用中看到开发者主账号AUTH TOKEN_accountToken = '4e831592bd464663b0de944df13f16ef'# 请使用管理控制台首页的APPID或自己创建应用的APPID_appId = '8aaf070868747811016883f12ef3062c'# 说明:请求地址,生产环境配置成app.cloopen.com_serverIP = 'sandboxapp.cloopen.com'# 说明:请求端口 ,生产环境为8883_serverPort = "8883"# 说明:REST API版本号保持不变_softVersion = '2013-12-26'# 云通讯官方提供的发送短信代码实例# 发送模板短信# @param to 手机号码# @param datas 内容数据 格式为数组 例如:{'12','34'},如不需替换请填 ''# @param $tempId 模板Iddef sendTemplateSMS(to, datas, tempId):# 初始化REST SDKrest = REST(_serverIP, _serverPort, _softVersion)rest.setAccount(_accountSid, _accountToken)rest.setAppId(_appId)result = rest.sendTemplateSMS(to, datas, tempId)print(result)for k, v in result.items():if k == 'templateSMS':for k, s in v.items():print('%s:%s' % (k, s))else:print('%s:%s' % (k, v))if __name__ == '__main__':# 注意: 测试的短信模板编号为1sendTemplateSMS('17600992168', ['123456', 5], 1)
5.模板短信SDK返回结果说明
{'statusCode': '000000', // 状态码。'000000'表示成功,反之,失败'templateSMS': {'smsMessageSid': 'b5768b09e5bc4a369ed35c444c13a1eb', // 短信唯一标识符'dateCreated': '20190125185207' // 短信发送时间}
}
3. 封装发送短信单例类
1.封装发送短信单例类
class CCP(object):"""发送短信的单例类"""def __new__(cls, *args, **kwargs):# 判断是否存在类属性_instance,_instance是类CCP的唯一对象,即单例if not hasattr(CCP, "_instance"):cls._instance = super(CCP, cls).__new__(cls, *args, **kwargs)cls._instance.rest = REST(_serverIP, _serverPort, _softVersion)cls._instance.rest.setAccount(_accountSid, _accountToken)cls._instance.rest.setAppId(_appId)return cls._instance
2.封装发送短信单例方法
def send_template_sms(self, to, datas, temp_id):"""发送模板短信单例方法:param to: 注册手机号:param datas: 模板短信内容数据,格式为列表,例如:['123456', 5],如不需替换请填 '':param temp_id: 模板编号,默认免费提供id为1的模板:return: 发短信结果"""result = self.rest.sendTemplateSMS(to, datas, temp_id)if result.get("statusCode") == "000000":# 返回0,表示发送短信成功return 0else:# 返回-1,表示发送失败return -1
3.测试单例类发送模板短信结果
if __name__ == '__main__':# 注意: 测试的短信模板编号为1CCP().send_template_sms('17600992168', ['123456', 5], 1)
4. 知识要点
- 容联云通讯只是发送短信的平台之一,还有其他云平台可用,比如,阿里云等,实现套路都是相通的。
- 将发短信的类封装为单例,属于性能优化的一种方案。
短信验证码后端逻辑
1. 短信验证码接口设计
1.请求方式
选项 | 方案 |
---|---|
请求方法 | GET |
请求地址 | /sms_codes/(?P1[3-9]\d{9})/ |
> | |
2.请求参数:路径参数和查询字符串 |
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
mobile | string | 是 | 手机号 |
image_code | string | 是 | 图形验证码 |
uuid | string | 是 | 唯一编号 |
> | |||
3.响应结果:JSON |
字段 | 说明 |
---|---|
code | 状态码 |
errmsg | 错误信息 |
2. 短信验证码接口定义
class SMSCodeView(View):"""短信验证码"""def get(self, reqeust, mobile):""":param reqeust: 请求对象:param mobile: 手机号:return: JSON"""pass
3. 短信验证码后端逻辑实现
class SMSCodeView(View):"""短信验证码"""def get(self, reqeust, mobile):""":param reqeust: 请求对象:param mobile: 手机号:return: JSON"""# 接收参数image_code_client = reqeust.GET.get('image_code')uuid = reqeust.GET.get('uuid')# 校验参数if not all([image_code_client, uuid]):return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})# 创建连接到redis的对象redis_conn = get_redis_connection('verify_code')# 提取图形验证码image_code_server = redis_conn.get('img_%s' % uuid)if image_code_server is None:# 图形验证码过期或者不存在return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码失效'})# 删除图形验证码,避免恶意测试图形验证码try:redis_conn.delete('img_%s' % uuid)except Exception as e:logger.error(e)# 对比图形验证码image_code_server = image_code_server.decode() # bytes转字符串if image_code_client.lower() != image_code_server.lower(): # 转小写后比较return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '输入图形验证码有误'})# 生成短信验证码:生成6位数验证码sms_code = '%06d' % random.randint(0, 999999)logger.info(sms_code)# 保存短信验证码redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)# 发送短信验证码CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)# 响应结果return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信成功'})
短信验证码前端逻辑
1. Vue绑定短信验证码界面
1.register.html
<li><label>短信验证码:</label><input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="msg_code" class="msg_input"><a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a><span class="error_tip" v-show="error_sms_code">[[ error_sms_code_message ]]</span>
</li>
2.register.js
check_sms_code(){if(this.sms_code.length != 6){this.error_sms_code_message = '请填写短信验证码';this.error_sms_code = true;} else {this.error_sms_code = false;}
},
2. axios请求短信验证码
1.发送短信验证码事件处理
send_sms_code(){// 避免重复点击if (this.sending_flag == true) {return;}this.sending_flag = true;// 校验参数this.check_mobile();this.check_image_code();if (this.error_mobile == true || this.error_image_code == true) {this.sending_flag = false;return;}// 请求短信验证码let url = '/sms_codes/' + this.mobile + '/?image_code=' + this.image_code+'&uuid='+ this.uuid;axios.get(url, {responseType: 'json'}).then(response => {if (response.data.code == '0') {// 倒计时60秒var num = 60;var t = setInterval(() => {if (num == 1) {clearInterval(t);this.sms_code_tip = '获取短信验证码';this.sending_flag = false;} else {num -= 1;// 展示倒计时信息this.sms_code_tip = num + '秒';}}, 1000, 60)} else {if (response.data.code == '4001') {this.error_image_code_message = response.data.errmsg;this.error_image_code = true;} else { // 4002this.error_sms_code_message = response.data.errmsg;this.error_sms_code = true;}this.generate_image_code();this.sending_flag = false;}}).catch(error => {console.log(error.response);this.sending_flag = false;})
},
2.发送短信验证码效果展示
补充注册时短信验证逻辑
1. 补充注册时短信验证后端逻辑
1.接收短信验证码参数
sms_code_client = request.POST.get('sms_code')
2.保存注册数据之前,对比短信验证码
redis_conn = get_redis_connection('verify_code')
sms_code_server = redis_conn.get('sms_%s' % mobile)
if sms_code_server is None:return render(request, 'register.html', {'sms_code_errmsg':'无效的短信验证码'})
if sms_code_client != sms_code_server.decode():return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})
2. 补充注册时短信验证前端逻辑
1.register.html
<li><label>短信验证码:</label><input type="text" v-model="sms_code" @blur="check_sms_code" name="sms_code" id="msg_code" class="msg_input"><a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a><span v-show="error_sms_code" class="error_tip">[[ error_sms_code_message ]]</span>{% if sms_code_errmsg %}<span class="error_tip">{{ sms_code_errmsg }} </span>{% endif %}
</li>
未完待续, 同学们请等待下一期
全套笔记资料代码移步: 前往gitee仓库查看
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
相关文章:

【Django开发】0到1美多商城项目md教程第4篇:图形验证码,1. 图形验证码接口设计【附代码文档】
美多商城完整教程(附代码资料)主要内容讲述:欢迎来到美多商城!,项目准备。展示用户注册页面,创建用户模块子应用。用户注册业务实现,用户注册前端逻辑。图形验证码,图形验证码接口设…...

八股 -- C#
面向对象 (三大特性) 三大特性目的是为了提供更好的代码组织、可维护性、扩展性和重用性 C#基础——面向对象 - 知乎 (zhihu.com) 封装 理解: 你不需要了解这个方法里面写了什么代码,你只需要了解这个方法能够给你返回什么数据&…...

科创新格局·共赢双循环“2024上海智能科技与创新展览会”
2024上海智能科技与创新展览会,将于6月中旬在上海新国际博览中心隆重召开。作为一场盛大的科技盛会,此次展览会将汇聚科技前瞻趋势,融合产业贸易优势,布局初创投资赛道,提供全方位场景生态的跨界合作,构建“…...

Chatopera 云服务的智能问答引擎实现原理,如何融合 #聊天机器人 技术 #Chatbot #AI #NLP
观看视频 Bilibili: https://www.bilibili.com/video/BV1pZ421q7EH/YouTube: https://www.youtube.com/watch?vx0d1_0HQa8o 内容大纲 提前在浏览器打开网址: Chatopera 云服务:https://bot.chatopera.comChatopera 入门教程:https://dwz…...

基于CNN-RNN的动态手势识别系统实现与解析
一、环境配置 为了成功实现基于CNN-RNN的动态手势识别系统,你需要确保你的开发环境已经安装了以下必要的库和工具: Python:推荐使用Python 3.x版本,作为主要的编程语言。TensorFlow:深度学习框架,用于构建…...
华为鲲鹏认证考试内容有哪些
华为鲲鹏认证考试的内容主要包括理论考核和实践考核两大部分。 在理论考核部分,主要考察考生对云计算、大数据、人工智能等相关领域的理论知识掌握情况,具体涉及体系结构、技术原理、应用场景等方面的内容。考生需要深入了解鲲鹏计算的特点,…...

Gitlab CI---could not read username for xxx: no such device or address
0 Preface/Foreword 项目开发中,经常会使用第三方的算法或者功能,那么就需要把对应的repo以子模块的方式添加到当前repo中。 添加命令: git submodule add <URL> 1 问题表现 子模块添加成功,但是GitLab CI阶段ÿ…...

三个AI创业方向各有特点和市场潜力
“AI 客户支持”乃成熟市场——B “AI 社交关系”属新旧交织之领域;——C “AI 企业知识”为专业化且对企业运营至要之领域——B AI 客户支持(Al customer support):此方向着重借助 AI 大模型技术,以改良和提升客户服务…...
C语言学习笔记二
文章目录 进制的代码表示数字数据类型字符类型输出字符例子 进制的代码表示 #include <stdio.h> int main() {short a 0100; // 八进制int b -0x1; // 十六进制long c 720; //十进制unsigned short m 0xffff; //十六进制unsigned int n 0x80000000; //十…...

Sublime Text4 4169 安装激活【亲测可用】
此教程用于Windows 下Sublime Text4 4169版本的安装和激活。 无需安装其他软件,无需下载替换文件,无需注册机等。 官网: https://www.sublimetext.com 下载地址 64位:https://download.sublimetext.com/sublime_text_build_41…...

【数据结构与算法初阶(c语言)】插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序-全梳理(万字详解,干货满满,建议三连收藏)
目录 1.排序的概念及其运用 1.1排序的概念 1.2排序运用 1.3常见的排序算法 2.插入排序 2.1 原理演示:编辑 2.2 算法实现 2.3 算法的时间复杂度和空间复杂度分析 3.希尔排序 3.1算法思想 3.2原理演示 3.3代码实现 3.4希尔算法的时间复杂度 4.冒泡排序 4.1冒泡排…...

[蓝桥杯 2019 省赛 AB] 完全二叉树的权值
# [蓝桥杯 2019 省 AB] 完全二叉树的权值 ## 题目描述 给定一棵包含 $N$ 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 $A_1,A_2, \cdots A_N$,如下图所示: 现在小明要把相同深度的节点的权值…...

亮数据Bright Data,引领高效数据采集新体验
随着互联网和大数据的日益普及,我们对于高速、安全和无限畅通的网络体验追求越发迫切,随之而来的网络安全和隐私保护变得越来越重要。IP代理作为一种实用的代理工具,可以高效地帮我们实现网络数据采集,有效解决网络安全问题&#…...
C#学习笔记
一、事件派发器 在C#中,事件派发器通常是指事件委托和事件处理程序的组合,用于实现一种观察者设计模式。它允许对象在状态发生变化时通知其他对象,从而实现对象之间的解耦。 事件派发器的基本组成部分: 事件委托(Ev…...

【A-006】基于SSH的新闻发布系统(含论文)
【A-006】基于SSH的新闻发布系统(含论文) 开发环境: Jdk7(8)Tomcat7(8)MySQLIntelliJ IDEA(Eclipse) 数据库: MySQL 技术: SpringStruts2HiberanteJSPJquery 适用于: 课程设计,毕业设计&…...

c语言-static
static作用:修饰变量和函数 修饰局部变量-静态局部变量 static未修饰局部变量 #include <stdio.h>void print() {int a 0;a;printf("%d ", a); }int main() {int i 0;for (i 0; i < 10; i){print();}return 0; }运行结果 static修饰局部变…...
zuul的性能调优
文章目录 zuul的性能调优Zuul参数剖析semaphore(信号量)ribbonhystrix高并发下常见Zuul异常熔断 zuul 1.x 与2.x的区别与总结 zuul的性能调优 在项目实践中,使用jemeter多线程并发访问微服务中的接口时候,在Zuul层出现异常、超时等,从而导致整…...

C++中的动态内存管理
1.C中动态内存管理 C语言内存管理方式在C中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。 1.1 new/delete操作内置类型 c语言和c的动态内存…...
es6的核心语法
在学习低代码时,经常有粉丝会问,低代码需要什么基础,es6就是基础中的一项。我们本篇是做一个扫盲,可以让你对基础有一个概要性的了解,具体的每个知识点可以深入进行了解,再结合官方模板就会有一个不错的掌握…...

Unity | 射线检测及EventSystem总结
目录 一、知识概述 1.Input.mousePosition 2.Camera.ScreenToWorldPoint 3.Camera.ScreenPointToRay 4.Physics2D.Raycast 二、射线相关 1.3D(包括UI)、射线与ScreenPointToRay 2.3D(包括UI)、射线与ScreenToWorldPoint …...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...