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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...