本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础。

  为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能。

  验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。

  图形验证码的历史比较悠久,到现在已经有点英雄末路的味道了。因为机器学习、图像识别的存在,机器人已经可以比较正确的识别图像内的字符了。但不管怎么说,作为一种防御手段,至少还是可以抵挡一些低级入门的攻击手段,抬高了攻击者的门槛。

验证码功能实现方法1——完整的验证码实现流程

1, 验证码前端画布页面生成

  那么下面我们将依次生成验证码这种画布,左边框是输入验证码的内容,右边框是设计验证码。

1.1,直接读取图片

  首先,我们需要了解读取图片的方法。

  # 方式一
with open('kd1.jpg', 'rb') as f:
data = f.read() return HttpResponse(data)

  这样我们知道方法就行,不建议使用,因为这样读取文件,我们需要存很多文件。

1.2,硬盘操作

  首先,我们需要导入库,图像处理库Pillow,如果没有的话,需要先安装pillow库。

  其次,我们创建一个定义随机颜色方法的函数。这函数的意义就是定义画布的背景颜色。

如何定义颜色随机呢?,因为三原色R,G,B的范围都是0-255,我们随机取0-255里面的某一个整数,就得到了随机颜色。代码如下:

#定义随机颜色方法
def get_random_color(): R = random.randrange(255)
G = random.randrange(255)
B = random.randrange(255) return (R,G,B)

  然后我们设定画布的大小,定义画布的宽和高。然后写一块区域,最后展示在前端页面。

    # 方式二:使用pillow PIL模块
# pip install pillow
from PIL import Image # img = Image.new("RGB", (270, 40), color='red')
img = Image.new("RGB", (270, 40), color=get_random_color())
with open("validCode.png", "wb") as f:
img.save(f, 'png')
with open('validCode.png', 'rb') as f:
data = f.read()
return HttpResponse(data)

  

1.3,内存操作

  其实硬盘操作,我们也不建议使用,最好的方法是建议使用内存操作。在上线中大多体验者需要的是速度,如果速度不够快,那就会放弃这个APP,所以我们一般牺牲其空间复杂度,换取时间复杂度。

  那内存操作如何做呢?首先,我们获取一个缓存区,然后将图片保存到缓存区,最后使用一个.getvalue的函数方法将缓存区的内容返回给前端。

  .getvalue  是把缓存区的所有数据读取。

  bytesIO() 是使用io 获取一个缓存区,然后将图片保存到缓存区,最后读取缓存区的数据。

    from PIL import Image, ImageDraw, ImageFont
from io import BytesIO img = Image.new('RGB', (270, 40), color=get_random_color()) f = BytesIO()
img.save(f, 'png')
data = f.getvalue()

  这样的话,一个前端画布就生成了,不仅生成了,我们还解决了速度问题,而且每次刷新,后台都会传出不同颜色的画布。

1.4 效果图

  验证码在前端显示,肯定是左边一格,右边一格。最后设计出来的画布效果是这样的。

  那下面,我们需要给画布里面添加文字了。

2,如何给面板里加文字

  我们需要导入绘图库 ImageDraw, 绘图字体库 ImageFont。还需要下载一个字体样式,直接使用网上的字体样式会比较简单。

2.1,ttf字体下载

  我们可以在网上下载一个ttf字体文件。选择一个自己喜欢的字体形式,下载。我这里下载了三个,这里我使用第三个 Vera.ttf字体。

2.2 添加文字

  一般情况下,验证码都是由四到八位不等的数字,大小写字母组成。我们这里选择五位,其中每个位里面让随机生成一个大写字母,或者小写字母,或者数字。然后将其保存下来。这就是一个简单的验证码就生成了。

  代码如下:

    # 导入绘图库
from PIL import Image, ImageDraw, ImageFont
# 导入IO库
from io import BytesIO img = Image.new('RGB', (270, 40), color=get_random_color())
draw = ImageDraw.Draw(img)
vera_font = ImageFont.truetype("static/font/Vera.ttf", size=35) # ttf 字体下载
valid_code_str = ''
for i in range(5):
# 数字
random_num = str(random.randint(0, 9))
# 随机小写字母
random_low_alpha = chr(random.randint(95, 122))
# 随机大写字母
random_upper_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_upper_alpha, random_low_alpha])
# x, y 坐标
draw.text((i*50+20, 5), random_char, get_random_color(), font=vera_font)
# 保存验证码字符串
valid_code_str += random_char

  

2.3 效果图

  验证码里面添加五个文字,最后设计出来的添加文字的画布效果是这样的。

3,加上噪点噪线

  其实上面差不多已经完成了验证码的操作,但是这是比较简单的验证码,一般的图片验证码机器就可以识别了。我们需要添加一些难度,比如噪点噪线。

  加噪点噪线也是为了减轻暴力请求,一般的图片验证码机器就可以识别出来,所以我们加点难度,这样可以减轻服务器的压力。

  下面代码中,width和height是前端画布的宽和高,第一个for循环是噪点的加入,第二个for循环是噪线的加入。

    width = 235
height = 35
for i in range(100):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw.line((x1, x2, y1, y2), fill=get_random_color()) for i in range(400):
draw.point([random.randint(0, width), random.randint(0, height)],
fill=get_random_color())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())

  x1, y1, x2, y2  则表示需要四个坐标。

3.1 效果图

   验证码里面添加噪点噪线,因为我还要使用,所以噪点噪线的效果就添加了一点点而已,如果需要复杂,可以添加内容就像,最后设计出来的添加噪点噪线的画布效果是这样的。

4,验证码局部刷新

  为什么要做验证码局部刷新呢?从使用者的角度来说,我们也知道,当前端显示的验证码看不清楚,我们就需要刷新一下,但是不可能不停的提交表单,这样的话,服务器的压力就太大了。所以这时候局部刷新就优势就显现出来了,我们需要局部刷新,很多人就想到了Ajax,没错,这是可以用,但是这里说一种比较简单的局部刷新的方法。

  我们可以看一个例子:

  从上面,我们发现可以使用增加字符的方式,实现局部刷新,那么我们也可以采取这么简单的方法,直接刷新验证码就行了。

  下面展示其代码:

<script src="/static/JS/jquery-3.2.1.js"></script>
<script>
//刷新验证码
$("#valid_code_img").click(function () {
$(this)[0].src += "?"
}) </script>

  views.py

def get_validCode_image(request):
def get_random_color():
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # 方式四,图片里面什么都没,这里我们需要加上噪点,文字
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO img = Image.new('RGB', (270, 40), color=get_random_color())
draw = ImageDraw.Draw(img)
vera_font = ImageFont.truetype("static/font/Vera.ttf", size=35) valid_code_str = ''
for i in range(5):
# 数字
random_num = str(random.randint(0, 9))
# 随机小写字母
random_low_alpha = chr(random.randint(95, 122))
# 随机大写字母
random_upper_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_upper_alpha, random_low_alpha])
# x, y 坐标
draw.text((i*50+20, 5), random_char, get_random_color(), font=vera_font)
# 保存验证码字符串
valid_code_str += random_char width = 235
height = 35
for i in range(10):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw.line((x1, x2, y1, y2), fill=get_random_color()) for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)],
fill=get_random_color())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color()) print('valid_code_str', valid_code_str) f = BytesIO()
img.save(f, 'png')
data = f.getvalue() request.session['valid_code_str'] = valid_code_str return HttpResponse(data)

  前端代码:

    // 登录验证
$(".login_btn").click(function () {
$.ajax({
url: "",
type: 'post',
data: {
user: $('#user').val(),
pwd: $('#pwd').val(),
valid_code: $("#valid_code").val(),
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
},
success: function (data) {
console.log(data);
if (data.user){
if (location.search){
location.href = location.search.slice(6)
}
else {
location.href = '/blog/index/'
}
}else {
$(".error").text(data.msg).css({'color':'red', 'margin-left':'10px'});
// 设置2秒后清空
setTimeout(function () {
$(".error").text("")
}, 2000)
}
}
})
});

  

5,cookie与session保存验证码

  将随机验证码存储到session中,就是需要记录给哪个请求发了什么验证码。

  为什么这么说呢?因为到时候使用登录验证的使用者不止一个人,那么服务端发送的验证码不记录给哪个请求发送的验证码,当好几个人同时请求验证码信息,然后提交,这样就会发生混淆。所以保险起见,我们使用session保存验证码。

   views.py

 request.session['valid_code_str'] = valid_code_str

  login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> <link rel="stylesheet" href="/static/blog/bootstrap-3.3.7-dist/css/bootstrap.css"> </head>
<body>
<h3 class=" text-center">登录页面</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-lg-offset-3">
<form>
{% csrf_token %}
<div class="form-group">
<label for="user">用户名</label>
<input type="text" id="user" class="form-control">
</div>
<div class="form-group">
<label for="pwd">密码</label>
<input type="password" id="pwd" class="form-control">
</div> <div class="form-group">
<label for="pwd">验证码</label>
<div class="row">
<div class="col-md-6">
<input type="text" id="valid_code" class="form-control">
</div>
<div class="col-md-6">
<img width="235" height="35" id="valid_code_img" src="/blog/get_validCode_image/" alt="">
</div>
</div>
</div> {# <input type="submit" class="btn btn-default login_btn pull-right" value="submit">#}
<input type="button" class="btn btn-default login_btn" value="submit"><span class="error"></span>
{# <input type="button" class="btn btn-default login_btn pull-right" value="submit">#}
</form>
</div>
</div>
</div> <script src="/static/JS/jquery-3.2.1.js"></script>
<script>
//刷新验证码
$("#valid_code_img").click(function () {
$(this)[0].src += "?"
}); // 登录验证
$(".login_btn").click(function () {
$.ajax({
url: "",
type: 'post',
data: {
user: $('#user').val(),
pwd: $('#pwd').val(),
valid_code: $("#valid_code").val(),
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
},
success: function (data) {
console.log(data);
if (data.user){
if (location.search){
location.href = location.search.slice(6)
}
else {
location.href = '/blog/index/'
}
}else {
$(".error").text(data.msg).css({'color':'red', 'margin-left':'10px'});
// 设置2秒后清空
setTimeout(function () {
$(".error").text("")
}, 2000)
}
}
})
}); </script>
</body> </html>

  index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Index Page</h1>
<p>{{ request.user.username }}</p>
</body>
</html>

  views.py

from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
# from .MyForms import UserTestForm
# from .models import UserTest
from django.http import JsonResponse
from django.contrib import auth
import random def login(request):
# if request.method == 'POST':
# response = {'user': None, 'msg': None}
#
# user = request.POST.get('user')
# pwd = request.POST.get('pwd')
# valid_code = request.POST.get('valid_code')
# valid_code_str = request.session.get('valid_code_str')
# # if valid_code == valid_code_str:
# # 验证码不区分大小写
# if valid_code.upper() == valid_code_str:
# pass
# else:
# # 校验失败了。。。。
# response['msg'] = 'valid code error!'
# pass
# return JsonResponse(response)
if request.method == 'POST':
print("POST..............")
response = {'user': None, 'msg': None}
user = request.POST.get('user')
pwd = request.POST.get('pwd')
valid_code = request.POST.get('valid_code') valid_code_str = request.session.get('valid_code_str')
# if valid_code == valid_code_str:
# 验证码不区分大小写
if valid_code.upper() == valid_code_str.upper():
user = auth.authenticate(username=user, password=pwd)
if user:
# request.user == 当前登录对象
auth.login(request, user)
response['user'] = user.username
pass
else:
# response['msg'] = 'username or password error !'
response['msg'] = '用户名或者密码错误'
else:
# 校验失败了。。。。
response['msg'] = 'valid code error!'
return JsonResponse(response) return render(request, 'login.html') def get_validCode_image(request):
from blog.utils.validCode import get_valid_code_img
data = get_valid_code_img(request)
return HttpResponse(data) def index(request):
return render(request, 'index.html')

  validCode.py

import random

def get_random_color():
return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) def get_valid_code_img(request): # # 方式一
# with open('kd1.jpg', 'rb') as f:
# data = f.read()
#
# return HttpResponse(data) # # 方式二:使用pillow PIL模块
# # pip install pillow
# from PIL import Image
#
# # img = Image.new("RGB", (270, 40), color='red')
# img = Image.new("RGB", (270, 40), color=get_random_color())
# with open("validCode.png", "wb") as f:
# img.save(f, 'png')
# with open('validCode.png', 'rb') as f:
# data = f.read()
# return HttpResponse(data) # 方式三,因为磁盘的方式比较慢,open是磁盘操作
# 内存操作会比较快,这里使用内存操作
# from PIL import Image, ImageDraw, ImageFont
# from io import BytesIO
#
# img = Image.new('RGB', (270, 40), color=get_random_color())
#
# f = BytesIO()
# img.save(f, 'png')
# data = f.getvalue() # 方式四,图片里面什么都没,这里我们需要加上噪点,文字
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO img = Image.new('RGB', (270, 40), color=get_random_color())
draw = ImageDraw.Draw(img)
vera_font = ImageFont.truetype("static/font/Vera.ttf", size=35)
# char = str(random.randint(0, 9)) # draw.text((0, 5), 'python', get_random_color(), font=vera_font)
# draw.text((0, 5), char, get_random_color(), font=vera_font)
# ttf 字体下载
valid_code_str = ''
for i in range(5):
# 数字
random_num = str(random.randint(0, 9))
# 随机小写字母
random_low_alpha = chr(random.randint(95, 122))
# 随机大写字母
random_upper_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_upper_alpha, random_low_alpha])
# x, y 坐标
draw.text((i*50+20, 5), random_char, get_random_color(), font=vera_font)
# 保存验证码字符串
valid_code_str += random_char width = 235
height = 35
for i in range(10):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
draw.line((x1, x2, y1, y2), fill=get_random_color()) for i in range(40):
draw.point([random.randint(0, width), random.randint(0, height)],
fill=get_random_color())
x = random.randint(0, width)
y = random.randint(0, height)
draw.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color()) print('valid_code_str', valid_code_str) request.session['valid_code_str'] = valid_code_str
'''
1, dasdasda
2, COOKIE {'sessionid': dsdsadsdad}
3,django-session
session-key session-data dsadasdsdsa
4,
'''
f = BytesIO()
img.save(f, 'png')
data = f.getvalue() return data

  

验证码功能实现方法2——captcha

  在Django中实现图片验证码功能非常简单,有现成的第三方库可以使用,我们不必自己开发(但是也需要自己能开发的出来,方法二将自己开发的图片验证码模块)。这个库叫做django-simple-captcha。

1,安装 captcha

  直接使用pip 按照

pip  install django--simple-captcha

  

  Django 自动帮我们安装了相关的依赖库 six, olefile 和 pillow ,其中Pillow是大名鼎鼎的绘图模块。

2,注册captcha

  在settings.py中,将'captcha' 注册到APP列表里。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user19',
'captcha',
]

  captcha 需要在数据库中建立自己的数据表,所以需要执行migrate命名生成数据表:

python manage.py makemigrations

python manage.py migrate

  

3,添加URL路由

  我们还需要在根目录下的urls.py文件添加 captcha 对应的网址:

from django.contrib import admin
from django.urls import path, include urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
path('captcha', include('captcha.urls')),
]

  

4,修改 myforms.py

  如果上面都OK了,就可以直接在MyForms.py文件中添加CaptchaField了。

from django import forms
from captcha.fields import CaptchaField class UserForm(forms.Form):
username = forms.CharField(label="用户名", max_length=128,
widget=forms.TextInput(attrs={'class': 'form-control'})) password = forms.CharField(label="密码", max_length=256,
widget=forms.PasswordInput(attrs={'class': 'form-control'})) captcha = CaptchaField(label='验证码')

  注意:我们需要提前导入form captcha.fields import CaptchaField ,然后就像写普通的form字段一样添加一个captcha字段就可以了。

5,HTML文件的使用(修改 login.html文件)

  由于我们这里直接学习验证码,所以我这里直接写一个简单的login.html页面,添加 capthca的相关内容。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> {% block content %}
<div class="container">
<div class="col-md-4 col-md-offset-4">
<form class='form-login' action="" method="post">
{% csrf_token %}
<h2 class="text-center">欢迎登录</h2>
<div class="form-group">
{{ login_form.username.label_tag }}
{{ login_form.username}}
</div>
<div class="form-group">
{{ login_form.password.label_tag }}
{{ login_form.password }}
</div> <div class="form-group">
{{ login_form.captcha.errors }}
{{ login_form.captcha.label_tag }}
{{ login_form.captcha }}
</div> <button type="submit" class="btn btn-primary pull-right">提交</button> </form>
</div>
</div>
{% endblock %} </body>
</html>

  这里额外的添加了一条 {{ login_form.captcha.errors }} 用于明确指示用户,你的验证码不正确。其中验证图形码是否正确的工作都是在后台自动完成的。只需要使用is_valid()这个myforms内置的验证方法就一起进行了,完全不需要再视图函数中添加任何的验证代码,非常方便快捷!

6,查看效果

  直接的效果进入页面的效果如下:

  我们输入错验证码的效果如下:

  当然我们还可以添加多种效果,这里就不做添加了,就实现简单的验证码功能即可。

7,附带的代码

  models.py

class UserTest(models.Model):
'''测试验证码,注册的用户表'''
name = models.CharField(max_length=128)
password = models.CharField(max_length=256) def __str__(self):
return self.name

  views.py

def login_test(request):
if request.method == 'POST':
login_form = UserTestForm(request.POST)
if login_form.is_valid():
username = login_form.cleaned_data['username']
password = login_form.cleaned_data['password']
try:
user = UserTest.objects.get(name=username)
if user.password == password:
return HttpResponse("OK")
else:
return HttpResponse("NG")
except:
return HttpResponse("NG")
return render(request, 'login_test.html', locals())
login_form = UserTestForm()
return render(request, 'login_test.html', locals())

  

验证码功能实现方法3——极验验证SDK

一,Django极验滑动验证码的使用

1,官网直接注册账号申请key和value

  极验滑动验证码官网:www.geetest.com

2,从Github: gt3-python-sdk下载.zip文件

3,找到里面Django 的文件夹对照官网直接copy

4,代码

  views.py

from geetest import GeetestLib
from django.contrib import auth
from django.http import JsonResponse
from django.shortcuts import render
def login(request):
if request.method == "POST":
# 初始化一个给AJAX返回的数据
ret = {"status": 0, "msg": ""}
# 从提交过来的数据中 取到用户名和密码
username = request.POST.get("username")
pwd = request.POST.get("password")
# 获取极验 滑动验证码相关的参数
gt = GeetestLib(pc_geetest_id, pc_geetest_key)
challenge = request.POST.get(gt.FN_CHALLENGE, '')
validate = request.POST.get(gt.FN_VALIDATE, '')
seccode = request.POST.get(gt.FN_SECCODE, '')
status = request.session[gt.GT_STATUS_SESSION_KEY]
user_id = request.session["user_id"] if status:
result = gt.success_validate(challenge, validate, seccode, user_id)
else:
result = gt.failback_validate(challenge, validate, seccode)
if result:
# 验证码正确
# 利用auth模块做用户名和密码的校验
user = auth.authenticate(username=username, password=pwd)
if user:
# 用户名密码正确
# 给用户做登录
auth.login(request, user) # 将登录用户赋值给 request.user
ret["msg"] = "/index/"
else:
# 用户名密码错误
ret["status"] = 1
ret["msg"] = "用户名或密码错误!"
else:
ret["status"] = 1
ret["msg"] = "验证码错误" return JsonResponse(ret)
return render(request, "login.html")
# 请在官网申请ID使用,示例ID不可使用
pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4" # 处理极验 获取验证码的视图
def get_geetest(request):
user_id = 'test'
gt = GeetestLib(pc_geetest_id, pc_geetest_key)
status = gt.pre_process(user_id)
request.session[gt.GT_STATUS_SESSION_KEY] = status
request.session["user_id"] = user_id
response_str = gt.get_response_str()
return HttpResponse(response_str)

  urls.py

from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
  url(r'^login/', views.login),
# 极验滑动验证码 获取验证码的url
url(r'^pc-geetest/register', views.get_geetest),
]

  login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎登录</title>
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/mystyle.css">
</head>
<body> <div class="container">
<div class="row">
<form class="form-horizontal col-md-6 col-md-offset-3 login-form">
{% csrf_token %}
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" name="username" placeholder="用户名">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="password" name="password" placeholder="密码">
</div>
</div>
<div class="form-group">
<!-- 放置极验的滑动验证码 -->
<div id="popup-captcha"></div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default" id="login-button">登录</button>
<span class="login-error"></span>
</div>
</div>
</form>
</div>
</div> <script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<!-- 引入封装了failback的接口--initGeetest -->
<script src="http://static.geetest.com/static/tools/gt.js"></script>
<script> // 极验 发送登录数据的
var handlerPopup = function (captchaObj) {
// 成功的回调
captchaObj.onSuccess(function () {
var validate = captchaObj.getValidate();
// 1. 取到用户填写的用户名和密码 -> 取input框的值
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
url: "/login/", // 进行二次验证
type: "post",
dataType: "json",
data: {
username: username,
password: password,
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
geetest_challenge: validate.geetest_challenge,
geetest_validate: validate.geetest_validate,
geetest_seccode: validate.geetest_seccode
},
success: function (data) {
console.log(data);
if (data.status) {
// 有错误,在页面上提示
$(".login-error").text(data.msg);
} else {
// 登陆成功
location.href = data.msg;
}
}
});
}); $("#login-button").click(function () {
captchaObj.show();
});
// 将验证码加到id为captcha的元素里
captchaObj.appendTo("#popup-captcha");
// 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
};
// 当input框获取焦点时将之前的错误清空
$("#username,#password").focus(function () {
// 将之前的错误清空
$(".login-error").text("");
}); // 验证开始需要向网站主后台获取id,challenge,success(是否启用failback)
$.ajax({
url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
type: "get",
dataType: "json",
success: function (data) {
// 使用initGeetest接口
// 参数1:配置参数
// 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
initGeetest({
gt: data.gt,
challenge: data.challenge,
product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
// 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
}, handlerPopup);
}
}) </script>
</body>
</html>

  

知识储备:python中chr() 函数 和 ord() 函数的用法。

1,chr()函数

格式: Chr(<数值表达式>)

说明:chr() 用一个范围在 range(256)内的(就是0~255)整数做参数。函数返回值类型为String,其数值表达式值取值范围为0~255,返回一个对应的字符(对应的ASCII字符)。

例如:Print(Chr(78))  结果显示:N

65-90  大写A-Z

97-122 小写的a-z

2,ord() 函数

格式: ord("字符串")

说明:函数返回值类型为int

例如:Print(ord('0'))  结果显示:48

参考文献:https://www.cnblogs.com/chimeiwangliang/p/7130434.html

Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现的更多相关文章

  1. Django学习笔记(19)——BBS+Blog项目开发(3)细节知识点补充

    本文将BBS+Blog项目开发中所需要的细节知识点进行补充,其中内容包括KindEditor编辑器的使用,BeautifulSoup 模块及其防XSS攻击,Django中admin管理工具的使用,me ...

  2. Django学习笔记(18)——BBS+Blog项目开发(2)主体思路及流程

    这篇博客主要完成一个BBS+Blog项目,那么主要是模仿博客园的博客思路,使用Django框架进行练习. 准备:项目需求分析 在做一个项目的时候,我们首先做的就是谈清楚项目需求,功能需求,然后才开始写 ...

  3. Django学习笔记(20)——BBS+Blog项目开发(4)Django如何使用Bootstrap

    本文学习如何通过Django使用Bootstrap.其实在之前好几个Django项目中已经尝试使用过了Bootstrap,而且都留有学习记录,我已经大概有了一个大的框架,那么本文就从头再走一遍流程,其 ...

  4. 项目实战:BBS+Blog项目开发

    01-博客系统之功能需求 02-博客系统之表结构设计1 03-博客系统之表结构设计2 04-博客系统之表结构设计3 05-博客系统之表结构设计4 06-博客系统之表机构设计5 07-博客系统之创建系统 ...

  5. IDEA 学习笔记之 Spark/SBT项目开发

    Spark/SBT项目开发: 下载Scala SDK 下载SBT 配置IDEA SBT:(如果不配置,就会重新下载SBT, 非常慢,因为以前我已经下过了,所以要配置为过去使用的SBT) 新建立SBT项 ...

  6. BBS+Blog项目开发

    BBS+Blog项目开发 目前本项目已经上线,可以直接在GEEK浏览本项目效果:GEEK 1.项目需求 基于ajax和用户认证组件实现登录验证 基于ajax和form组件实现注册功能 系统首页文章列表 ...

  7. Django学习笔记之利用Form和Ajax实现注册功能

    一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...

  8. Django学习笔记(9)—— 开发用户注册与登录系统

    一,项目题目: 开发用户注册与登录系统 该项目主要练习使用Django开发一个用户注册与登录的系统,通过这个项目然后巩固自己这段时间所学习的Django知识. 二,项目需求: 开发一个简单的用户登录与 ...

  9. Django学习笔记(一)——安装,创建项目,配置

    疯狂的暑假学习之 Django学习笔记(一) 教材  书<The Django Book> 视频:csvt Django视频 1.创建项目 django‐admin.py startpro ...

随机推荐

  1. 【LOJ#575】【LNR#2】不等关系(容斥,动态规划,分治FFT)

    [LOJ#575][LNR#2]不等关系(容斥,动态规划,分治FFT) 题面 LOJ 题解 一个暴力\(dp\),设\(f[i][j]\)表示考虑完了前\(i\)个位置,其中最后一个数在前面所有数中排 ...

  2. mosquitto配置文件

    #配置文件为mosquitto #参见mosquitto.conf(5)了解更多信息. #显示默认值,取消注释以更改. #使用#字符来表示注释,但只有当它是 #第一个字符就行了. #========= ...

  3. MySQL for OPS 12:锁处理

    写在前面的话 在前面的内容中提到过,在以前的 MyISAM 中锁是表级锁,InnoDB 是行级锁.这个锁到底是啥样,怎么找出来,这一节就主要做这个. 定位锁的问题 上一节我们创建了一个 1000万数据 ...

  4. arcgis api 3.x for js 地图加载多个气泡窗口展示(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  5. 962. Maximum Width Ramp

    本题题意: 在数组中,找到最大的j-i,使得i<j and A[i] <= A[j] 思路: 维持一个递减的栈,遇到比栈顶小的元素,进栈: 比大于等于栈顶的元素-> 找到栈中第一个小 ...

  6. Cygwin添加右键菜单

    修改注册表 统一的方式,添加一个右键命令 找到HKEY_CLASSES_ROOT\Directory\Background\shell 右键,新建项.名字随便起 再次右键,新建项.命名command ...

  7. 9.智能快递柜SDK(串口型锁板)

    1.智能快递柜(开篇) 2.智能快递柜(终端篇) 3.智能快递柜(通信篇-HTTP) 4.智能快递柜(通信篇-SOCKET) 5.智能快递柜(通信篇-Server程序) 6.智能快递柜(平台篇) 7. ...

  8. iOS 应用程序启动时要做什么

    当您的应用程序启动(无论是在前台或后台),使用您的应用程序委托application:willFinishLaunchingWithOptions:和application:didFinishLaun ...

  9. this license XXXXXX has been cancelled

    this license XXXXXX has been cancelled问题解决:首先修改hosts 文件 加入0.0.0.0 account.jetbrains.comhosts 目录 wind ...

  10. linux查询及添加用户

    1.查询用户. 存储帐号的文件:/etc/passwd 存储密码的文件:/etc/shadow Cat  /etc/passwd Cat  /etc/shadow 2.添加用户 输入命令: usera ...