BBS论坛(十三)

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

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

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

(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='参数错误')

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

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
13.1点击更换图形验证码
13.2.短信验证码
13.3.短信验证码加密
13.4.验证码缓存


13-----BBS论坛的更多相关文章

  1. Python之路,Day17 - 分分钟做个BBS论坛

    Python之路,Day17 - 分分钟做个BBS论坛   本节内容: 项目:开发一个简单的BBS论坛 需求: 整体参考"抽屉新热榜" + "虎嗅网" 实现不同 ...

  2. LNMP环境搭建BBS论坛及伪静态

    我们在mysql备份 LNMP环境中的数据库迁移为独立的服务器的基础上搭建BBS论坛:  [root@bqh-117 ~]# mysql -uroot -p123456 Welcome to the ...

  3. Python之路【第十八篇】Django小项目简单BBS论坛部分内容知识点

    开发一个简单的BBS论坛 项目需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可被 ...

  4. python 学习笔记二十 django项目bbs论坛

    项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...

  5. python第一百三十天 ---简单的BBS论坛

    简单的BBS论坛 实现功能 git仓库地址:https://github.com/uge3/BBS 1.整体参考“抽屉新热榜” + “博客园” 2.实现不同论坛版块 3.帖子列表展示 4.个人博客主页 ...

  6. Django小项目简单BBS论坛

    开发一个简单的BBS论坛 项目需求: 1 整体参考"抽屉新热榜" + "虎嗅网" 2 实现不同论坛版块 3 帖子列表展示 4 帖子评论数.点赞数展示 5 在线用 ...

  7. Python开发一个简单的BBS论坛

    项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...

  8. bbs论坛浏览器兼容性问题

    一直都是在chrome上进行调试,今天终于把bbs论坛这个项目搭建完了,进入IE.Firefox看了看 吓哭了!!! 火狐 Edge chrome 特别是加了<!DOCTYPE html> ...

  9. 开源BBS论坛软件推荐

    七款开源BBS论坛软件推荐(1) 本文介绍了七个开源的BBS论坛软件(在英文界一般叫做Forum).可能国内的朋友们比较熟悉Discuz!和PHPwind,但其实我们的选择还是很多的,而且下面介绍的这 ...

  10. Django项目 BBS论坛

    BBS论坛 一.项目表分析 二.自定义form组件 三.注册功能 四.BBS论坛 登录功能

随机推荐

  1. windows 7 系统装机优化

    A:系统设置 1.控制面板\系统和安全\Windows Update\更改设置  把系统升级以及提示关闭      控制面板\系统和安全\Windows 防火墙\自定义设置 把专用网络和公共网络的防火 ...

  2. 解析IFC数据并存储到关系型数据库

    即系IFC数据并存储到关系型数据库中,目前解析的IFC文件是两亿多行,构件数量120万

  3. 基于unity3d的RRT算法路径规划

  4. vray学习笔记(5)-学习资料

    首先肯定是vray的官方的资料了: 一个是教程 https://docs.chaosgroup.com/display/VRAY3MAX/Tutorials 一个是帮助文件 https://docs. ...

  5. EZOJ #81

    传送门 分析 每次拿a中最大的去匹配b中最小的 至于原因画个图感性思考一下就可以啦 代码 #include<iostream> #include<cstdio> #includ ...

  6. Excel神技能

    按住ALT再按数字41420就可打对号 按住ALT再按数字41409就可打叉号

  7. 浅谈assert()函数的用法

    #include<stdio.h> #include<assert.h> char * Strcpy(char *dst,const char *src) { assert(d ...

  8. labview中的移位寄存器、循环隧道,自动索引隧道的区别

    对于循环结构(For 循环.while循环)而言,循环体内的数据域外部数据的传递是通过以下三种方式: 1.移位寄存器2.循环隧道3.自动索引隧道 第一.各自的区别.作用 循环隧道,就是把数据传入传出循 ...

  9. 按失真类型分类整理IQA数据集:TID2013

    前面已经整理了TID2008,这次整理TID2013的工作相对较简单,只需要改代码的一部分就可以了,首先我大概介绍一些TID2013. TID2013是TID2008的加强版,链接如下:http:// ...

  10. SLAM(Linux版)

    之前的那个是Windows版,现在终于发现Windows运行slam是不行的,多么痛的领悟. 本书系统地介绍了视觉SLAM所需的基本知识与核心算法,既包括数学理论基础,如三维空间的刚体运动.非线性优化 ...