BBS論壇(十三)

来源:https://www.cnblogs.com/derek1184405959/archive/2018/06/08/9157718.html
-Advertisement-
Play Games

13.1點擊更換圖形驗證碼 (1)front/signup.html (2)static/front/css/signup.css body { background: #f3f3f3; } .outer-box { width: 854px; background: #fff; margin: 0 ...


13.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;
}
body {
    background: #f3f3f3;
}

.outer-box {
    width: 854px;
    background: #fff;
    margin: 0 auto;
    overflow: hidden;
}

.logo-box {
    text-align: center;
    padding-top: 40px;
}

.logo-box img {
    width: 60px;
    height: 60px;
}

.page-title {
    text-align: center;
}

.sign-box {
    width: 300px;
    margin: 0 auto;
    padding-top: 50px;
}

.captcha-addon {
    padding: 0;
    overflow: hidden;
}

.captcha-img {
    width: 94px;
    height: 32px;
    cursor: pointer;
}
View Code

(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;
    }
};
View Code

(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') }}">

現在點擊驗證碼,就可以更換驗證碼了。

 

13.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
View Code

(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']);
                }
            }
        });
    });
});

 

13.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='參數錯誤')
View Code

(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']);
                }
            }
        });
    });
});
View Code

(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>

 

13.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
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • wframe不是控制項庫,也不是UI庫,她是一個微信小程式面向對象編程框架,代碼只有幾百行。她的主要功能是規範小程式項目的文件結構、規範應用程式初始化、規範頁面載入及授權管理的框架,當然,wframe也提供了一些封裝好了的函數庫,方便開發者調用。 wframe目前已實現的核心功能: 1. 應用程式初始 ...
  • define和typedef的區別 define是單純的字元替換,typedef是重新定義了新的類型 ...
  • Java面向對象的三大特性之繼承一:繼承的概念;二:類的繼承格式;三:為什麼需要繼承;四:繼承的特性;五:繼承的關鍵字; ...
  • def func1(seq1): dic={ 'num':0, 'string':0, 'space':0, 'other':0 } for line in seq1: if line.isdigit(): dic['num'] += 1 elif line.isalpha(): dic['stri ...
  • Java中的內部類一:什麼是內部類;二:Java 中的成員內部類;三:Java 中的靜態內部類;四:Java 中的方法內部類; ...
  • 就是想記錄一下 JSP中傳參的四種方法: 1、form表單 2、request.setAttribute();和request.getAttribute(); 3、超鏈接:<a herf="index.jsp"?a=a&b=b&c=c>name</a> 4、<jsp:param> 發生Referen ...
  • python從2.6開始支持format,新的更加容易讀懂的字元串格式化方法, 從原來的% 模式變成新的可讀性更強的 綜合舉例說明: 輸入: '{:>18,.2f}'.format(70305084.0) # :冒號+空白填充+右對齊+固定寬度18+浮點精度.2+浮點數聲明f 輸出:' 70,305 ...
  • 原創 三羊獻瑞 觀察下麵的加法算式: 祥 瑞 生 輝 + 三 羊 獻 瑞 三 羊 生 瑞 氣 (如果有對齊問題,可以參看【圖1.jpg】) 其中,相同的漢字代表相同的數字,不同的漢字代表不同的數字。 請你填寫“三羊獻瑞”所代表的4位數字(答案唯一),不要填寫任何多餘內容。 分析:三羊生瑞氣這個數中三 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...