ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

开源web框架django知识总结(九)

2021-11-23 09:03:38  阅读:120  来源: 互联网

标签:web code 短信 get image redis 验证码 django 开源


开源web框架django知识总结(九)

容联云通讯短信平台

1. 容联云通讯短信平台介绍

1.容联云官网

  • 容联云通讯网址:https://www.yuntongxun.com/
  • 注册并登陆

在这里插入图片描述
2、登录后,主控台
在这里插入图片描述
3、容联云创建应用
在这里插入图片描述
4、创建应用
在这里插入图片描述
5、填写应用信息
在这里插入图片描述
6、认证1
在这里插入图片描述
7、认证2
在这里插入图片描述
8、认证3
在这里插入图片描述
9、添加测试号
在这里插入图片描述
10、模板信息
在这里插入图片描述
注意:没上线,可以跳过认证那几步。

2. 容联云通讯短信SDK测试

1.模板短信SDK下载

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

2.模板短信SDK使用说明

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

3.集成模板短信SDK

  • CCPRestSDK.py:由容联云通讯开发者编写的官方SDK文件,包括发送模板短信的方法
  • ccp_sms.py:调用发送模板短信的方法
    在这里插入图片描述
    4.模板短信SDK测试
  • ccp_sms.py文件中(修改4个地方)
# -*- coding:utf-8 -*-
 
from verifications.libs.yuntongxun.CCPRestSDK import REST
 
# 说明:主账号,登陆云通讯网站后,可在"控制台-应用"中看到开发者主账号ACCOUNT SID
_accountSid = ''
 
# 说明:主账号Token,登陆云通讯网站后,可在控制台-应用中看到开发者主账号AUTH TOKEN
_accountToken = ''
 
# 请使用管理控制台首页的APPID或自己创建应用的APPID
_appId = ''
 
# 说明:请求地址,生产环境配置成app.cloopen.com
_serverIP = 'sandboxapp.cloopen.com'
 
# 说明:请求端口 ,生产环境为8883
_serverPort = "8883"
 
# 说明:REST API版本号保持不变
_softVersion = '2013-12-26'
 
# 云通讯官方提供的发送短信代码实例
# 发送模板短信
# @param to 手机号码
# @param datas 内容数据 格式为数组 例如:{'12','34'},如不需替换请填 ''
# @param $tempId 模板Id
def sendTemplateSMS(to, datas, tempId):
    # 初始化REST SDK
    rest = 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__':
    # 注意: 测试的短信模板编号为1
    sendTemplateSMS('已注册的测试手机号', ['123456', 5], 1)  #注意 前面手机号,必须你你设置的测试号

注意:需要自己修改的地方
在这里插入图片描述

if __name__ == '__main__':
    # 注意: 测试的短信模板编号为1
    sendTemplateSMS('已注册的测试手机号', ['123456', 5], 1)  #注意 前面手机号,必须你你设置的测试号

5.模板短信SDK返回结果说明**

{
    'statusCode': '000000', // 状态码。'000000'表示成功,反之,失败
    'templateSMS': 
        {
            'smsMessageSid': 'b5768b09e5bc4a369ed35c444c13a1eb', // 短信唯一标识符
            'dateCreated': '20190125185207' // 短信发送时间
        }
}

图形验证码

1、新建名字为:verifications 的 app,安装第三方包Pillow

python ../../manage.py startapp verifications
pip install pillow

注意,项目所在的虚拟环境和项目路径
在这里插入图片描述

2、从虚拟机下载app

3、在dev.py中,注册verifications

在这里插入图片描述
4、在verifications的app中,新建urls.py文件

from django.urls import re_path
from users.views import *

urlpatterns = [

]

5、项目总路由中,添加verifications的子路由

urlpatterns = [
    path('admin/', admin.site.urls),

    # 总路由的正则为空,表示总路由不会匹配任何路径前缀,把完整的路径交给子路由匹配
    re_path(r'', include('users.urls')),
    re_path(r'', include('verifications.urls')),

]

6、在项目的根目录建立第三方导入的libs包,复制已经准备好的captcha扩展包(同时也把下面要用到的yuntongxun包复制过来)

在这里插入图片描述
7、准备Redis的2、3号库存储验证码数据,注意比较写法上哪些不同

"verify_code": { # 存储验证码数据
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
 "sms_code": { # 存储验证码数据
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/3",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },

在这里插入图片描述
注:云服务器上需开放redis配置,否则外网访问,看不到redis图片

vim /root/redis-stable/redis.conf (我当前虚拟机/etc/redis/redis.conf )

#注释bind
#bind 127.0.0.1

修改后,重启Redis服务器。

sudo /etc/init.d/redis_6379 stop

sudo /etc/init.d/redis_6379 start

8、根据项目文档要求,在verifications的app中的views.py中写图片验证码代码

views.py内容:

from django.views import View    # 从django.views导入View
from aerf_mall.libs.captcha.captcha import captcha #导入第三方包captcha
from django_redis import get_redis_connection  # 导入redis库
from django.http import HttpResponse   # 导入HttpResponse给前端进行响应
# Create your views here.

import logging    # 导入日记模块
logger = logging.getLogger('django')

# 图形验证码接口
class ImageCodeView(View):

    def get(self, request, uuid):
        # 1、调用库生成图形验证码
        text, image = captcha.generate_captcha()
        # 2、存储redis
        conn = get_redis_connection('verify_code')
        try:
            # 验证码写入redis
            conn.setex(
                "img_%s"%uuid,
                300,
                text
            )
        except Exception as e:
            print(e)
            logger.error(e)
        # 3、构建响应
        return HttpResponse(image, content_type='image/jpg')

9、根据项目文档要求,在verifications的app中的urls.py中写图片验证码接口

from django.urls import re_path # 从django.urls导入re_path
from . import views # 从当前文件夹,导入views

urlpatterns = [
    # 图形验证码
    re_path(r'^image_codes/(?P<uuid>[\w-]+)/$', views.ImageCodeView.as_view()),
]

10、测试

http://127.0.0.1/register.html
测试Redis数据库:17307114007

redis-cli
select 2
keys *
get img_45c2f9f0-d382-4da4-aa6c-ce33db0b8712

容联云通讯短信

短信验证码接口定义、后端逻辑分析

1、请求方式:get

2、获取用户网页输入的内容:‘image_code’、‘image_code_id’ (request.GET.get())

3、校验参数:a、是否都有数据?b、校验验证码数据长度和格式(4位,正则re) c、校验uuid格式

4、校验用户输入的图形验证码,与Redis数据库中的是否一致。

get_redis_connection('verify_code')
.get("img_%s"%uuid)

5、如果没从Redis读到数据,向前端提示“验证码过期”

6、读到数据,用.decode()解码,删除原始数据:conn.delete(“img_%s”%uuid)

7、比对(忽略大小写)image_code.lower() != image_code_from_redis.lower():

8、发送短息要花钱的,如果上面校验没问题,才开始准备发送短信验证码

a)连接Redis的’sms_code’库,

b)检查60秒内,是否给同一个手机号,发送过短信
9、调用容联云发送短信接口。

10、向前端返回“成功”状态码

补充知识点: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()

短信验证码接口定义、后端逻辑代码实现

views.py

from django.http import HttpResponse,JsonResponse
from aerf_mall.libs.yuntongxun.ccp_sms import CCP
import random  # 注意如果使用快速导包,可能回出现 from random import random 代码会报错,要注意

import re
# 短信验证码接口
class SMSCodeView(View):

    def get(self, request, mobile):

        # 1、提取参数
        image_code = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')

        # 2、校验参数
        if not all([image_code, uuid]):
            return JsonResponse({
                'code': 400,
                'errmsg': '缺少必要参数'
            }, status=400)
        if not re.match(r'^\w{4}$', image_code):
            return JsonResponse({
                'code': 400,
                'errmsg': '图片验证码格式不符'
            }, status=400)
        if not re.match(r'^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$', uuid):
            return JsonResponse({
                'code': 400,
                'errmsg': 'uuid格式不符'
            }, status=400)

        # 3、校验redis中的图片验证码是否一致——业务层面上的校验
        conn = get_redis_connection('verify_code')
        # 3.1 提取redis中存储的图片验证码
        # get(): b"YBCF"
        image_code_from_redis = conn.get("img_%s"%uuid)

        # 如果从redis中读出的验证码是空;
        if not image_code_from_redis:
            return JsonResponse({'code':400, 'errmsg': '验证码过期'}, status=400)
        # 如果读出来的不是空,我们要删除该验证码
        image_code_from_redis = image_code_from_redis.decode()
        conn.delete("img_%s"%uuid)

        # 3.2 比对(忽略大小写)
        if image_code.lower() != image_code_from_redis.lower():
            return JsonResponse({
                'code': 400,
                'errmsg': '图形验证码输入错误'
            }, status=400)


        # 4、发送短信验证码
        conn = get_redis_connection('sms_code')
        # 判断60秒之内,是否发送过短信——判断标志信息是否存在
        flag = conn.get('flag_%s'%mobile)
        if flag:
            return JsonResponse({'code':400, 'errmsg':'请勿重复发送短信'}, status=400)

        # 构建6位手机验证码
        sms_code = "%06d"%random.randint(0, 999999)
        print("手机验证码:", sms_code)

        # 生成一个redis的pipeline对象
        p = conn.pipeline()
        # 把验证码存入redis
        p.setex(
            "sms_%s"%mobile,
            300,
            sms_code
        )
        # 一旦用户发送了短信,需要在redis中存储一个标志
        p.setex(
            "flag_%s"%mobile,
            60,
            '1'
        )
        p.execute() # 批量执行队列中的指令

        # 发送验证码
        # 同步调用——只有当该发送短信当函数执行完毕,且返回了;代码才会继续往后执行!
        # 如果网络出现了问题,该函数就会一致阻塞在此,导致我们的视图函数无法即使响应!
        CCP().send_template_sms(mobile, [sms_code, 5], 1)


        return JsonResponse({
            'code': 0,
            'errmsg': 'ok'
        })

urls.py

# 获取短信验证码的子路由:
    re_path(r'^sms_codes/(?P<mobile>1[3-9]\d{9})/$', views.SMSCodeView.as_view()),

测试Redis数据库:

redis-cli
select 3
keys *
get sms_13939396666

在这里插入图片描述

祝大家学习python顺利!

标签:web,code,短信,get,image,redis,验证码,django,开源
来源: https://blog.csdn.net/weixin_54733110/article/details/121464056

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有