BBS论坛(十三)
13.1點(diǎn)擊更換圖形驗(yàn)證碼
(1)front/signup.html
<div class="form-group"><div class="input-group"><input type="text" class="form-control" name="graph_captcha" placeholder="圖形驗(yàn)證碼"><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') }}">現(xiàn)在點(diǎn)擊驗(yàn)證碼,就可以更換驗(yàn)證碼了。
?
13.2.短信驗(yàn)證碼
(1)utils/alidayu.py
# 仙劍論壇-阿里大于短信驗(yàn)證碼sdkimport hashlib from time import time import logging import requestsclass 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.configtry: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('請?zhí)顚懻_的阿里大魚配置!')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'] = telephonenewparams = "".join(["%s%s" % (k, v) for k, v in sorted(self.api_params.items())])newparams = self.secret + newparams + self.secretsign = hashlib.md5(newparams.encode("utf-8")).hexdigest().upper()self.api_params['sign'] = signresp = 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 resultexcept: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 = '仙劍論壇網(wǎng)站' 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 Captchabp = 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='請輸入手機(jī)號碼')#生成四位數(shù)的驗(yàn)證碼captcha = Captcha.gene_text(number=4)if alidayu.send_sms(telephone,code=captcha):return restful.success()else:# return restful.params_error(message='短信驗(yàn)證碼發(fā)送失敗!')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);//獲取手機(jī)號碼var telephone = $("input[name='telephone']").val();//使用js的正則判斷手機(jī)號碼,如果不合法,彈出提示框,直接return回去if (!(/^1[3578]\d{9}$/.test(telephone))) {zlalert.alertInfoToast('請輸入正確的手機(jī)號');return;}zlajax.get({'url': '/c/sms_captcha?telephone='+telephone,'success': function (data) {if(data['code'] == 200){zlalert.alertSuccessToast('短信驗(yàn)證碼發(fā)送成功');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('發(fā)送驗(yàn)證碼');}},1000);}else{zlalert.alertInfoToast(data['message']);}}});}); });?
13.3.短信驗(yàn)證碼加密
(1)common/forms.py
from apps.forms import BaseForm from wtforms import StringField from wtforms.validators import regexp,InputRequired import hashlibclass 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 Falsetelephone=self.telephone.datatimestamp=self.timestamp.datasign=self.sign.datasign2=hashlib.md5((timestamp+telephone+self.salt).encode('utf-8')).hexdigest()if sign==sign2:return Trueelse: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 SMSCaptchaFormbp = 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='請輸入手機(jī)號碼') # #生成四位數(shù)的驗(yàn)證碼 # captcha = Captcha.gene_text(number=4) # if alidayu.send_sms(telephone,code=captcha): # return restful.success() # else: # # return restful.params_error(message='短信驗(yàn)證碼發(fā)送失敗!') # return restful.success() @bp.route('/sms_captcha/',methods=['POST']) def sms_captcha(): # telephone+timestamp+saltform=SMSCaptchaForm(request.form)if form.validate():telephone=form.telephone.datacaptcha=Captcha.gene_text(number=4)if alidayu.send_sms(telephone,code=captcha):return restful.success()else:# return restful.paramas_error(message='參數(shù)錯誤')return restful.success()else:return restful.params_error(message='參數(shù)錯誤') View Code(3)front_signup.js
$(function () {$("#sms-captcha-btn").click(function (event) {event.preventDefault();var self = $(this);//獲取手機(jī)號碼var telephone = $("input[name='telephone']").val();//使用js的正則判斷手機(jī)號碼,如果不合法,彈出提示框,直接return回去if (!(/^1[3578]\d{9}$/.test(telephone))) {zlalert.alertInfoToast('請輸入正確的手機(jī)號');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('短信驗(yàn)證碼發(fā)送成功');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('發(fā)送驗(yàn)證碼');}}, 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.驗(yàn)證碼緩存
把front/views里面的圖形驗(yàn)證碼放到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 BytesIObp = 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='請輸入手機(jī)號碼') # #生成四位數(shù)的驗(yàn)證碼 # captcha = Captcha.gene_text(number=4) # if alidayu.send_sms(telephone,code=captcha): # return restful.success() # else: # # return restful.params_error(message='短信驗(yàn)證碼發(fā)送失敗!') # return restful.success() @bp.route('/sms_captcha/', methods=['POST']) def sms_captcha():# telephone+timestamp+saltform = SMSCaptchaForm(request.form)if form.validate():telephone = form.telephone.datacaptcha = Captcha.gene_text(number=4)if alidayu.send_sms(telephone, code=captcha):zlcache.set(telephone, captcha) # 驗(yàn)證碼保存到緩存中return restful.success()else:# return restful.paramas_error(message='參數(shù)錯誤')zlcache.set(telephone, captcha) # 測試用return restful.success()else:return restful.params_error(message='參數(shù)錯誤')@bp.route('/captcha/') def graph_captcha():text,image = Captcha.gene_graph_captcha()zlcache.set(text.lower(),text.lower())out = BytesIO()image.save(out,'png') #指定格式為pngout.seek(0) #把指針指到開始位置resp = make_response(out.read())resp.content_type = 'image/png'return resp View Code?
總結(jié)
- 上一篇: 绝对定位和相对定位的口诀---子绝父相
- 下一篇: vagrant 本地添加box 支持带版