处理流程

  用户请求网页 --> 后台发送登录界面的静态页面 --> 后台在内存中生成验证码 --> 验证码保存在用户对应的Session中 --> 返回验证码图片到前端

  用户登录界面再加载生成后的图片验证码 --> 用户提交数据 --> 匹配相应的文本框和Session中的验证码

HTML页面

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/>
<link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="/static/css/edmure.css"/>
<link rel="stylesheet" href="/static/css/commons.css"/>
<link rel="stylesheet" href="/static/css/account.css"/>
</head>
<body>
<div class="login">
<div style="font-size: 25px; font-weight: bold;text-align: center;">
用户登陆
</div>
<form role="form" action="/login.html" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" placeholder="请输入密码">
</div>
<div class="form-group">
<label for="password">验证码</label> <div class="row">
<div class="col-xs-7">
<input type="text" class="form-control" placeholder="请输入验证码" name="check_code">
</div>
<div class="col-xs-5">
<img src="/check_code.html" onclick="changeCheckCode(this);">
<!-- <img src="/static/imgs/avatar/20130809170025.png"> -->
</div>
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> 一个月内自动登陆
</label>
<div class="right">
<a href="#">忘记密码?</a>
</div>
</div>
<button type="submit" class="btn btn-default">登 陆</button>
</form>
</div>
<script>
function changeCheckCode(ths){
ths.src = ths.src + '?';  <!--改变URL,刷新图片。-->
}
</script>
</body>
</html>

处理函数

from io import BytesIO
from django.shortcuts import HttpResponse
from django.shortcuts import render
from utils.check_code import create_validate_code def check_code(request):
stream = BytesIO() #开辟一块内存空间,不用写在外存,减少读写操作
img, code = create_validate_code()
img.save(stream,'PNG')
request.session['CheckCode'] = code
return HttpResponse(stream.getvalue())
def login(request):
if request.method == 'POST':
code = request.POST.get('check_code')
if code.upper() == request.session['CheckCode'].upper():
print('验证码正确')
else:
print('验证码错误')
return render(request, 'login.html')

生成图片的工具包

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(120, 30),
chars=init_chars,
img_type="GIF",
mode="RGB",
bg_color=(255, 255, 255),
fg_color=(0, 0, 255),
font_size=18,
font_type="Monaco.ttf",#依赖字体,需要下载相应的字体文件
length=4,
draw_lines=True,
n_line=(1, 2),
draw_points=True,
point_chance=2):
"""
@todo: 生成验证码图片
@param size: 图片的大小,格式(宽,高),默认为(120, 30)
@param chars: 允许的字符集合,格式字符串
@param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
@param mode: 图片模式,默认为RGB
@param bg_color: 背景颜色,默认为白色
@param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
@param font_size: 验证码字体大小
@param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
@param length: 验证码字符个数
@param draw_lines: 是否划干扰线
@param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
@param draw_points: 是否画干扰点
@param point_chance: 干扰点出现的概率,大小范围[0, 100]
@return: [0]: PIL Image实例
@return: [1]: 验证码图片中的字符串
""" width, height = size # 宽高
# 创建图形
img = Image.new(mode, size, bg_color)
draw = ImageDraw.Draw(img) # 创建画笔 def get_chars():
"""生成给定长度的字符串,返回列表格式"""
return random.sample(chars, length) def create_lines():
"""绘制干扰线"""
line_num = random.randint(*n_line) # 干扰线条数 for i in range(line_num):
# 起始点
begin = (random.randint(0, size[0]), random.randint(0, size[1]))
# 结束点
end = (random.randint(0, size[0]), random.randint(0, size[1]))
draw.line([begin, end], fill=(0, 0, 0)) def create_points():
"""绘制干扰点"""
chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] for w in range(width):
for h in range(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=(0, 0, 0)) def create_strs():
"""绘制验证码字符"""
c_chars = get_chars()
strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开 font = ImageFont.truetype(font_type, font_size)
font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3),
strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines:
create_lines()
if draw_points:
create_points()
strs = create_strs() # 图形扭曲参数
params = [1 - float(random.randint(1, 2)) / 100,
0,
0,
0,
1 - float(random.randint(1, 10)) / 100,
float(random.randint(1, 2)) / 500,
0.001,
float(random.randint(1, 2)) / 500
]
img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大) return img, strs

Django学习-25-图片验证码实例的更多相关文章

  1. django学习之- 动态验证码学习

    实例:通过前台和后台,实现用户登录页面动态图片验证码校验,图片验证码部分使用Pillow模块实现,作为单独学习部分记录. 前端: <!DOCTYPE html> <html lang ...

  2. Python开发【Django】:图片验证码、KindEditor

    图片验证码 生成图片验证码需要以下: session check_code.py(依赖:Pillow,字体文件) 模块安装 pip install Pillow src属性后面加? 在utils下拷贝 ...

  3. Django学习手册 - 登录验证码

    生成验证码函数 import random from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = " ...

  4. Django学习之天气调查实例(1):工程的开始

    开始学习Django,一步一个脚印的进行.思考再三,还是以一个实例来开始学习.手里面正好有几万条单位天气传感器收集的数据,想做一个网页版的天气统计查询之类的小应用,也可以给学生体验,方便教学的进行(尽 ...

  5. Django学习-14-分页功能实例

    首先创建一个制作page的工具类                     utils                         --page_make.py                    ...

  6. Django学习之天气调查实例(3):部署静态文件CSS、JS、images等(部署环境基于Ubuntu)

    在设计登录界面时,采用了网上下载的登录模板,漂亮,简易.但是在测试和部署时,发现原来模板中采用的js文件和css文件,却着实让我折腾了好几天. 在以往的网页设计中,一般只要把测试站点开启后,网页中的静 ...

  7. Django学习之天气调查实例(2):显示数据表数据

    数据表数据添加后,如添加3条用户信息,分别为“aaa”.“bbb”.“ccc”,现在通过代码的方式显示数据表中的数据. 1.在website项目文件夹中创建 userload.py文件,并且写如下代码 ...

  8. django学习-25.admin管理后台里:把表名称和表字段名称的展示值都由英文显示改为由中文显示

    目录结构 1.前言 2.完整的操作步骤 2.1.第一步:修改模型类Article 2.2.第二步:重启服务 2.3.第三步:退出登录并再次成功登陆admin管理后台 2.4.第四步:查看最新的表名称展 ...

  9. Django实战(一)-----用户登录与注册系统5(图片验证码)

    为了防止机器人频繁登录网站或者破坏分子恶意登录,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是一种区分用户是计算机还是人的公共全自动程序. 可以防止恶意破解密码.刷票.论坛 ...

随机推荐

  1. SpringMVC源码情操陶冶-AnnotationDrivenBeanDefinitionParser注解解析器

    mvc:annotation-driven节点的解析器,是springmvc的核心解析器 官方注释 Open Declaration org.springframework.web.servlet.c ...

  2. BZOJ 1982: [Spoj 2021]Moving Pebbles [博弈论 对称]

    给你N堆Stone,两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就输了... 以前在poj做过已经忘记了... 构造对称,选最多的一堆往其他堆分 ...

  3. 小甲鱼OD学习第11讲

    这次我们的任务是破解这个需要注册的软件,如下图所示 我们这次从字符串入手,我们查找 unregistered  字符串 然后我们在如下图的字符串下断点 然后我们来到断点处,我们观察到 地址为 0040 ...

  4. ubuntu的网络配置

    1,检查网络是否通畅 ping www.baidu.com 2,检查网线是否插好 3,使用ifconfig查看当前活跃网络接口 ifconfig 4,配置IP地址.子网掩码.网关地址 sudo vi ...

  5. UML设计

    UML设计 1. UML的概念 Unified Modeling Language(UML)又称统一建模语言或标准建模语言,是一个支持模型化和软件系统开发的图形化语言.为软件开发的所有阶段提供模型化和 ...

  6. 脚本实现centos7修改二块网卡名称并配置ip信息

    #!/bin/bash interface1=`ls /sys/class/net|grep en|awk 'NR==1{print}'`interface2=`ls /sys/class/net|g ...

  7. 开启Nginx的目录文件列表功能

    ngx_http_autoindex_module  此模块用于自动生成目录列表,ngx_http_autoindex_module只在 ngx_http_index_module模块未找到索引文件时 ...

  8. 装x玩法:插上你的专有U盘才能开机

    玩法的效果是这样的: 1.插上你的专有U盘,按电脑开机按钮,电脑正常启动运行: 2.如果不插专有优U盘,按电脑开机按钮,进入桌面后1秒钟电脑自动关机,无法使用.也就是说,没有优U盘将无法使用你的电脑. ...

  9. git使用步骤

    1报名出处: git config --global user.name lhp  用户名 git config --global user.email a@.qq.com 邮箱 2.建立项目文件夹: ...

  10. 基于JDK1.8的LinkedList剖析

    之前写了一篇ArrayList,那么今天就写一篇他的姊妹篇,LinkedList. 众所周知,ArrayList底层数据是数组,可以在O(1)的时间内get到数据,但删除和插入就要O(n)时间复杂度. ...