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

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

容联云通讯短信平台

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

1.容联云官网

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

开源web框架django知识总结(九)_第1张图片
2、登录后,主控台
开源web框架django知识总结(九)_第2张图片
3、容联云创建应用
开源web框架django知识总结(九)_第3张图片
4、创建应用
开源web框架django知识总结(九)_第4张图片
5、填写应用信息
开源web框架django知识总结(九)_第5张图片
6、认证1
开源web框架django知识总结(九)_第6张图片
7、认证2
开源web框架django知识总结(九)_第7张图片
8、认证3
开源web框架django知识总结(九)_第8张图片
9、添加测试号
开源web框架django知识总结(九)_第9张图片
10、模板信息
开源web框架django知识总结(九)_第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:调用发送模板短信的方法
    开源web框架django知识总结(九)_第11张图片
    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)  #注意 前面手机号,必须你你设置的测试号

注意:需要自己修改的地方
开源web框架django知识总结(九)_第12张图片

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

注意,项目所在的虚拟环境和项目路径
开源web框架django知识总结(九)_第13张图片

2、从虚拟机下载app

3、在dev.py中,注册verifications

开源web框架django知识总结(九)_第14张图片
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包复制过来)

开源web框架django知识总结(九)_第15张图片
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",
        }
    },

开源web框架django知识总结(九)_第16张图片
注:云服务器上需开放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[\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/(?P1[3-9]\d{9})/$', views.SMSCodeView.as_view()),

测试Redis数据库:

redis-cli
select 3
keys *
get sms_13939396666

开源web框架django知识总结(九)_第17张图片

祝大家学习python顺利!

你可能感兴趣的:(python,django,ubuntu,django,python,原力计划,web框架,后端)