flask爱家租房项目开发(三)

本节代码下载地址:https://download.csdn.net/download/geek_xiong/11527723

目录

 

短信验证码

云通讯的基本配置

云通讯发送短信验证码工具封装与测试

发送短信验证码 后端代码编写

图片、短信验证码测试

短信验证码的前端完善


短信验证码

本文参考文档下载地址:https://download.csdn.net/download/geek_xiong/11527723

本项目基于云通讯实现短信验证码的发送与验证

云通讯的基本配置

flask爱家租房项目开发(三)_第1张图片

下载短信接口包:https://www.yuntongxun.com/doc/ready/demo/1_4_1_2.html

开发文档自行观看。

由于下载的包是基于python2.7写的,但是本项目是用的python3.7,所示下载的文件中需要进行升级,我把改后的文件以及需要的文件打包上传了,可自行下载 https://download.csdn.net/download/geek_xiong/11523100

flask爱家租房项目开发(三)_第2张图片

添加测试号码,最好输入有效手机号,要不怎么接收验证码嘞!

云通讯发送短信验证码工具封装与测试

将yuntongxun包解压后放到ihome目录的libs子目录下,

编写测试文档sms.py,自定义封装发送短信验证码的辅助类

# -*- coding: UTF-8 -*-

from ihome.libs.yuntongxun.CCPRestSDK import REST
import configparser

#主帐号
accountSid = '8a216dxxxxxxxxxxxxxx4d82f0dd6'

#主帐号Token
accountToken = '154xxxxxxxxxxxxxxxxxxx325cc52a3f'

#应用Id
appId = '8a216dxxxxxxxxxxxxxxxxxxxxxxxx8004d8850ddd'

#请求地址,格式如下,不需要写http://
serverIP = 'app.cloopen.com'

#请求端口 
serverPort = '8883'

#REST版本号
softVersion='2013-12-26'

  # 发送模板短信
  # @param to 手机号码
  # @param datas 内容数据 格式为数组 例如:{'12','34'},如不需替换请填 ''
  # @param $tempId 模板Id


class CCP(object):
    """自己封装的发送短信的辅助类"""
    # 用来保存对象的类属性
    instance = None
    def __new__(cls):
        # 判断CCP类有没有创建好的对象,如果没有,创建一个对象,如果有,直接返回
        if cls.instance is None:
            obj = super(CCP, cls).__new__(cls)

            # 初始化REST yuntongxun
            obj.rest = REST(serverIP, serverPort, softVersion)
            obj.rest.setAccount(accountSid, accountToken)
            obj.rest.setAppId(appId)

            cls.instance = obj
        return cls.instance


    def sendTemplateSMS(self, to, datas, temp_Id):

        result = self.rest.sendTemplateSMS(to,datas,temp_Id)
        # 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))
        # statusCode:     000000
        # smsMessageSid:  54987ccdd2bbxxxxxxxxxxxx7de7ac93aa
        # dateCreated:    20190811193012
        status_code = result.get('statusCode')
        if status_code == '000000':
            return 0  # 000000表示发送成功
        return -1  # 发送失败

if __name__ == '__main__':
    ccp = CCP()
    ret = ccp.sendTemplateSMS('1513xxxxxxx', ["123", "456"], 1)
    print(ret)
   
# sendTemplateSMS(手机号码,内容数据,模板Id)

运行一下这个测试文件,如果填写的手机收到验证码,并且终端上打印 0 就表示成功了

发送短信验证码 后端代码编写

url:127.0.0.1:5000/api/vi.0/sms_codes/?image_code=xxx&image_code_id=xxx

需要传的参数为手机号mobile,image_code和image_code_id可以在request中直接获取

大致流程:

  • 获取参数:获取image_code与image_code_id
  • 检验参数:验证这两个数据是否完整
  • 业务逻辑处理
    • 从redis中取出image_code_id对应的真实值
    • 判断真实值是否过期
    • 对比用户输入的验证码与真实值是否相等
    • 判断手机号是否已注册
    • 生成短信验证码
    • 将手机号对应的短信验证码保存到redis中
    • 向注册手机号发送短信验证码
    • 判断发送是否成功
  • 返回值(上述中已经返回)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random

from flask import current_app, jsonify, make_response, request

from . import api
from ihome.utils.captcha.captcha import captcha
from ihome import redis_store, constants, db
from ihome.utils.response_code import RET
from ihome.models import User
from ihome.libs.yuntongxun.sms import CCP

...

# GET 127.0.0.1:5000/sms_codes/?image_code=xxx&image_code_id=xxx

@api.route("/sms_codes/")
def get_sms_code(mobile):
    """获取短信验证码"""
    # 获取参数
    image_code = request.args.get('image_code')
    image_code_id = request.args.get('image_code_id')

    # 检验参数
    if not all([image_code, image_code_id]):
        # 参数不完整
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 逻辑处理
    # 从redis中取出验证码图片的真实值
    try:
        real_image_code = redis_store.get('image_code_%s' % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库异常')

    # 判断真实值是否过期,redis中如果过期则返回None
    if real_image_code is None:
        return jsonify(errno=RET.NODATA, errmsg='验证码失效')

    # 验证用户填写的验证码与redis中的真实值是否相等
    if image_code.lower() != real_image_code.lower():
        return jsonify(errno=RET.DATAERR, errmssg='图片验证码错误')

    # 判断手机号是否已注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
    else:
        if user is not None:
            return jsonify(errno=RET.DATAEXIST, errmsg='手机号已注册')

    # 生成短信验证码 6 位
    # import random
    sms_code = "%06d" % random.randint(0, 999999)  # %06d  表示生成6位整数,不够的前边补0 ,如029541

    # 保存短信验证码到redis中
    try:
        redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='短信验证码保存异常')

    # 发送短信验证码
    try:
        # from ihome.libs.yuntongxun.sms import CCP
        ccp = CCP()
        result = ccp.sendTemplateSMS(mobile, [sms_code, int(constants.SMS_CODE_REDIS_EXPIRES/60)], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='验证码发送异常')

    if result == 0:
        # 发送成功
        return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')

图片、短信验证码测试

启动项目,刷新一下浏览器

flask爱家租房项目开发(三)_第3张图片

flask爱家租房项目开发(三)_第4张图片

打开postman,先测试一个假的数据

请求方式选择GET,填写地址“127.0.0.1:5000/api/v1.0/sms_codes”,点击右边的Params,分别填入key-value,点击Send,观察左下角的body,应该返回的是“图片验证码错误”

flask爱家租房项目开发(三)_第5张图片

返回的和预想的一样,修改验证码image_code的值为正确的,再验证一下。

注意:

  • 验证码有效期
  • 手机号在云通讯中未注册

flask爱家租房项目开发(三)_第6张图片

验证码失效了,刷新了一下

flask爱家租房项目开发(三)_第7张图片

现在输入正确的image_code与image_code_id(手机号是错误的)

flask爱家租房项目开发(三)_第8张图片

手机号是正确的

flask爱家租房项目开发(三)_第9张图片

短信验证码的前端完善

flask爱家租房项目开发(三)_第10张图片

页面点击 “ 获取验证码 ” 的时候,需要判断手机号和图片验证码是否填写,如果没有填写,给出提醒,按钮恢复状态(或者不变或者取消点击状态),都填写并正确的情况下,发送短信验证码,按钮开始倒计时,并取消点击状态,当倒计时结束时恢复点击状态

function sendSMSCode() {
    $(".phonecode-a").removeAttr("onclick");
    var mobile = $("#mobile").val();
    if (!mobile) {
        $("#mobile-err span").html("请填写正确的手机号!");
        $("#mobile-err").show();
        $(".phonecode-a").attr("onclick", "sendSMSCode();");
        return;
    } 
    var imageCode = $("#imagecode").val();
    if (!imageCode) {
        $("#image-code-err span").html("请填写验证码!");
        $("#image-code-err").show();
        $(".phonecode-a").attr("onclick", "sendSMSCode();");
        return;
    }
    $.get("/api/v1.0/sms_codes/"+mobile, {image_code:imageCode, image_code_id:imageCodeId},
        function(data){
            if (0 != data.errno) {
                $("#image-code-err span").html(data.errmsg); 
                $("#image-code-err").show();
                if (2 == data.errno || 3 == data.errno) {
                    generateImageCode();
                }
                $(".phonecode-a").attr("onclick", "sendSMSCode();");
            }   
            else {
                var $time = $(".phonecode-a");
                var duration = 60;
                var intervalid = setInterval(function(){
                    $time.html(duration + "秒"); 
                    if(duration === 1){
                        clearInterval(intervalid);
                        $time.html('获取验证码'); 
                        $(".phonecode-a").attr("onclick", "sendSMSCode();");
                    }
                    duration = duration - 1;
                }, 1000, 60); 
            }
    }, 'json'); 
}

flask爱家租房项目开发(三)_第11张图片

根据评论,已添加sms.py所在图

flask爱家租房项目开发(三)_第12张图片

本节完

 

 

 

 

 

 

你可能感兴趣的:(python3)