美文网首页FLASK入门
点击更换图形验证码和发送短信验证码(十三)

点击更换图形验证码和发送短信验证码(十三)

作者: Zhang_derek | 来源:发表于2018-06-12 18:00 被阅读9次

    1.点击更换图形验证码

    (1)front/signup.html

      <div class="form-group">
                    <div class="input-group">
                        <input type="text" class="form-control" name="graph_captcha" placeholder="图形验证码">
                        <span class="input-group-addon captcha-addon">
                            <img id="captcha-img" class="captcha-img" src="{{ url_for('front.graph_captcha') }}" alt="">
                        </span>
                    </div>
                </div>
    

    (2)static/front/css/signup.css

    .sign-box {
        width: 300px;
        margin: 0 auto;
        padding-top: 50px;
    }
    
    .captcha-addon {
        padding: 0;
        overflow: hidden;
    }
    
    .captcha-img {
        width: 94px;
        height: 32px;
        cursor: pointer;
    }
    

    (3)static/common/zlparam.js

    var zlparam = {
        setParam: function (href,key,value) {
            // 重新加载整个页面
            var isReplaced = false;
            var urlArray = href.split('?');
            if(urlArray.length > 1){
                var queryArray = urlArray[1].split('&');
                for(var i=0; i < queryArray.length; i++){
                    var paramsArray = queryArray[i].split('=');
                    if(paramsArray[0] == key){
                        paramsArray[1] = value;
                        queryArray[i] = paramsArray.join('=');
                        isReplaced = true;
                        break;
                    }
                }
    
                if(!isReplaced){
                    var params = {};
                    params[key] = value;
                    if(urlArray.length > 1){
                        href = href + '&' + $.param(params);
                    }else{
                        href = href + '?' + $.param(params);
                    }
                }else{
                    var params = queryArray.join('&');
                    urlArray[1] = params;
                    href = urlArray.join('?');
                }
            }else{
                var param = {};
                param[key] = value;
                if(urlArray.length > 1){
                    href = href + '&' + $.param(param);
                }else{
                    href = href + '?' + $.param(param);
                }
            }
            return href;
        }
    };
    

    (4)static/front/js/signup.js

    $(function () {
       $('#captcha-img').click(function (event) {
           var self= $(this);
           var src = self.attr('src');
           var newsrc = zlparam.setParam(src,'xx',Math.random());
           self.attr('src',newsrc);
       });
    });
    

    (5)front/signup.html中引用js和css

     <script src="{{ static('common/zlparam.js') }}"></script>
        <script src="{{ static('front/js/front_signup.js') }}"></script>
        <link rel="stylesheet" href="{{ static('front/css/front_signup.css') }}">
    

    现在点击验证码,就可以更换验证码了。

    2.短信验证码

    (1)utils/alidayu.py

    # 仙剑论坛-阿里大于短信验证码sdk
    
    import hashlib
    from time import time
    import logging
    import requests
    
    class AlidayuAPI(object):
    
        APP_KEY_FIELD = 'ALIDAYU_APP_KEY'
        APP_SECRET_FIELD = 'ALIDAYU_APP_SECRET'
        SMS_SIGN_NAME_FIELD = 'ALIDAYU_SIGN_NAME'
        SMS_TEMPLATE_CODE_FIELD = 'ALIDAYU_TEMPLATE_CODE'
    
        def __init__(self, app=None):
            self.url = 'https://eco.taobao.com/router/rest'
            self.headers = {
                'Content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
                "Cache-Control": "no-cache",
                "Connection": "Keep-Alive",
            }
            if app:
                self.init_app(app)
    
    
        def init_app(self,app):
            config = app.config
            try:
                self.key = config[self.APP_KEY_FIELD]
                self.secret = config[self.APP_SECRET_FIELD]
                self.sign_name = config[self.SMS_SIGN_NAME_FIELD]
                self.api_params = {
                    'sms_free_sign_name': config[self.SMS_SIGN_NAME_FIELD],
                    'sms_template_code': config[self.SMS_TEMPLATE_CODE_FIELD],
                    'extend': '',
                    'sms_type': "normal",
                    "method": "alibaba.aliqin.fc.sms.num.send",
                    "app_key": self.key,
                    "format": "json",
                    "v": "2.0",
                    "partner_id": "",
                    "sign_method": "md5",
                }
            except Exception as e:
                logging.error(e.args)
                raise ValueError('请填写正确的阿里大鱼配置!')
    
    
        def send_sms(self,telephone,**params):
            self.api_params['timestamp'] = str(int(time() * 1000))
            self.api_params['sms_param'] = str(params)
            self.api_params['rec_num'] = telephone
    
            newparams = "".join(["%s%s" % (k, v) for k, v in sorted(self.api_params.items())])
            newparams = self.secret + newparams + self.secret
            sign = hashlib.md5(newparams.encode("utf-8")).hexdigest().upper()
            self.api_params['sign'] = sign
    
            resp = requests.post(self.url,params=self.api_params,headers=self.headers)
            data = resp.json()
            try:
                result = data['alibaba_aliqin_fc_sms_num_send_response']['result']['success']
                return result
            except:
                print('='*10)
                print("阿里大于错误信息:",data)
                print('='*10)
                return False
    

    (2)exts.py

    alidayu = AlidayuAPI()
    

    (3)config.py

    ALIDAYU_APP_KEY = 'LTxxxxxxBBfT8Q'
    ALIDAYU_APP_SECRET = 'SRxxxxxx8IL8LhJ'
    ALIDAYU_SIGN_NAME = '仙剑论坛网站'
    ALIDAYU_TEMPLATE_CODE = 'SMS_136xxx947'
    

    (4)perfect_bbs.py

    alidayu.init_app(app)
    

    (5)common/views.py

    # common/views.py
    __author__ = 'derek'
    
    from flask import Blueprint,request
    from exts import alidayu
    from utils import restful
    from utils.captcha import Captcha
    
    bp = Blueprint("common",__name__,url_prefix='/c')
    
    @bp.route('/sms_captcha/')
    def sms_captcha():
        telephone = request.args.get('telephone')
        if not telephone:
            return restful.params_error(message='请输入手机号码')
        #生成四位数的验证码
        captcha = Captcha.gene_text(number=4)
        if alidayu.send_sms(telephone,code=captcha):
            return restful.success()
        else:
            # return restful.params_error(message='短信验证码发送失败!')
            return restful.success()
    

    (6)signup.html

     <script src="{{ static('common/zlajax.js') }}"></script>
        <link rel="stylesheet" href="{{ static("common/sweetalert/sweetalert.css") }}">
        <script src="{{ static("common/sweetalert/sweetalert.min.js") }}"></script>
        <script src="{{ static("common/sweetalert/zlalert.js") }}"></script>
        <script src="{{ static('common/zlparam.js') }}"></script>
        <script src="{{ static('front/js/front_signup.js') }}"></script>
        <link rel="stylesheet" href="{{ static('front/css/front_signup.css') }}">
    

    (7)front_signup.js

    $(function () {
        $("#sms-captcha-btn").click(function (event) {
            event.preventDefault();
            var self = $(this);
            //获取手机号码
            var telephone = $("input[name='telephone']").val();
            //使用js的正则判断手机号码,如果不合法,弹出提示框,直接return回去
            if (!(/^1[3578]\d{9}$/.test(telephone))) {
                zlalert.alertInfoToast('请输入正确的手机号');
                return;
            }
            zlajax.get({
                'url': '/c/sms_captcha?telephone='+telephone,
                'success': function (data) {
                    if(data['code'] == 200){
                        zlalert.alertSuccessToast('短信验证码发送成功');
                        self.attr("disabled",'disabled');
                        var timeCount = 60;
                        var timer = setInterval(function () {
                            timeCount--;
                            self.text(timeCount);
                            if(timeCount <= 0){
                                self.removeAttr('disabled');
                                clearInterval(timer);
                                self.text('发送验证码');
                            }
                        },1000);
                    }else{
                        zlalert.alertInfoToast(data['message']);
                    }
                }
            });
        });
    });
    

    3.短信验证码加密

    (1)common/forms.py

    from apps.forms import BaseForm
    from wtforms import StringField
    from wtforms.validators import regexp,InputRequired
    import hashlib
    
    class SMSCaptchaForm(BaseForm):
        salt='dfurtn5hdsesjc*&^nd'
        telephone=StringField(validators=[regexp(r'1[3578]\d{9}')])
        timestamp=StringField(validators=[regexp(r'\d{13}')])
        sign=StringField(validators=[InputRequired()])
    
        def validate(self):
            result=super(SMSCaptchaForm, self).validate()
            if not result:
                return False
            telephone=self.telephone.data
            timestamp=self.timestamp.data
            sign=self.sign.data
    
            sign2=hashlib.md5((timestamp+telephone+self.salt).encode('utf-8')).hexdigest()
            if sign==sign2:
                return True
            else:
                return False
    

    (2)front/views.py

    # common/views.py
    __author__ = 'derek'
    
    from flask import Blueprint,request
    from exts import alidayu
    from utils import restful
    from utils.captcha import Captcha
    from .form import SMSCaptchaForm
    
    bp = Blueprint("common",__name__,url_prefix='/c')
    
    # @bp.route('/sms_captcha/')
    # def sms_captcha():
    #     telephone = request.args.get('telephone')
    #     if not telephone:
    #         return restful.params_error(message='请输入手机号码')
    #     #生成四位数的验证码
    #     captcha = Captcha.gene_text(number=4)
    #     if alidayu.send_sms(telephone,code=captcha):
    #         return restful.success()
    #     else:
    #         # return restful.params_error(message='短信验证码发送失败!')
    #         return restful.success()
    @bp.route('/sms_captcha/',methods=['POST'])
    def sms_captcha():
    #     telephone+timestamp+salt
        form=SMSCaptchaForm(request.form)
        if form.validate():
            telephone=form.telephone.data
            captcha=Captcha.gene_text(number=4)
            if alidayu.send_sms(telephone,code=captcha):
                return restful.success()
            else:
                 # return restful.paramas_error(message='参数错误')
                return restful.success()
        else:
            return restful.params_error(message='参数错误')
    

    (3)front_signup.js

    $(function () {
        $("#sms-captcha-btn").click(function (event) {
            event.preventDefault();
            var self = $(this);
            //获取手机号码
            var telephone = $("input[name='telephone']").val();
            //使用js的正则判断手机号码,如果不合法,弹出提示框,直接return回去
            if (!(/^1[3578]\d{9}$/.test(telephone))) {
                zlalert.alertInfoToast('请输入正确的手机号');
                return;
            }
            var timestamp = (new Date).getTime();
            var sign = md5(timestamp + telephone + 'dfurtn5hdsesjc*&^nd');
            zlajax.post({
                'url': '/c/sms_captcha/',
                'data': {
                    'telephone': telephone,
                    'timestamp': timestamp,
                    'sign': sign
                },
                'success': function (data) {
                    if (data['code'] == 200) {
                        zlalert.alertSuccessToast('短信验证码发送成功');
                        self.attr("disabled", 'disabled');
                        var timeCount = 60;
                        var timer = setInterval(function () {
                            timeCount--;
                            self.text(timeCount);
                            if (timeCount <= 0) {
                                self.removeAttr('disabled');
                                clearInterval(timer);
                                self.text('发送验证码');
                            }
                        }, 1000);
                    } else {
                        zlalert.alertInfoToast(data['message']);
                    }
                }
            });
        });
    });
    

    (4)front/signup.html

     <meta name="csrf-token" content="{{ csrf_token() }}">
    
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
    

    4.验证码缓存

    把front/views里面的图形验证码放到common/views.py下面
    common/views.py

    # common/views.py
    __author__ = 'derek'
    
    from flask import Blueprint, request,make_response
    from exts import alidayu
    from utils import restful, zlcache
    from .form import SMSCaptchaForm
    from utils.captcha import Captcha
    from io import BytesIO
    
    bp = Blueprint("common", __name__, url_prefix='/c')
    
    
    # @bp.route('/sms_captcha/')
    # def sms_captcha():
    #     telephone = request.args.get('telephone')
    #     if not telephone:
    #         return restful.params_error(message='请输入手机号码')
    #     #生成四位数的验证码
    #     captcha = Captcha.gene_text(number=4)
    #     if alidayu.send_sms(telephone,code=captcha):
    #         return restful.success()
    #     else:
    #         # return restful.params_error(message='短信验证码发送失败!')
    #         return restful.success()
    @bp.route('/sms_captcha/', methods=['POST'])
    def sms_captcha():
        #     telephone+timestamp+salt
        form = SMSCaptchaForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            captcha = Captcha.gene_text(number=4)
            if alidayu.send_sms(telephone, code=captcha):
                zlcache.set(telephone, captcha)  # 验证码保存到缓存中
                return restful.success()
            else:
                # return restful.paramas_error(message='参数错误')
                zlcache.set(telephone, captcha)  # 测试用
                return restful.success()
        else:
            return restful.params_error(message='参数错误')
    
    
    @bp.route('/captcha/')
    def graph_captcha():
        text,image = Captcha.gene_graph_captcha()
        zlcache.set(text.lower(),text.lower())
        out = BytesIO()
        image.save(out,'png')   #指定格式为png
        out.seek(0)             #把指针指到开始位置
        resp = make_response(out.read())
        resp.content_type = 'image/png'
        return resp
    

    相关文章

      网友评论

        本文标题:点击更换图形验证码和发送短信验证码(十三)

        本文链接:https://www.haomeiwen.com/subject/fgereftx.html