Django自定义插件实现网站登录验证码功能


Posted in Python onApril 19, 2017

前言

网站登录的时候我们常常会看到随机的验证码需要输入后台验证,如图:

Django自定义插件实现网站登录验证码功能

现在我们来实现在Django中通过自定制插件来实现随机验证

check_code.py

基于PIL生成一个带验证码的图片和验证码,生成验证码图片需要Monaco.ttf字体(重要),可按自己要求更改check_code中的字体和字体文件位置

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
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

创建urls和views

views.py:

# 将check_code包放在合适的位置,导入即可,我是放在utils下面
from utils import check_code
 
def create_code_img(request):
  f = BytesIO() #直接在内存开辟一点空间存放临时生成的图片
 
  img, code = check_code.create_validate_code() #调用check_code生成照片和验证码
  request.session['check_code'] = code #将验证码存在服务器的session中,用于校验
  img.save(f,'PNG') #生成的图片放置于开辟的内存中
  return HttpResponse(f.getvalue()) #将内存的数据读取出来,并以HttpResponse返回

urls我的设置:url(r'^create_code_img/', views.create_code_img) 

前端应用验证码和点击自动刷新

html:

<div class="row">
  <div class="col-xs-7">
    <input type="text" class="form-control" name="check_code" id="check_code" placeholder="请输入验证码">
  </div>
  <div class="col-xs-5">
   <img id="check_code_img" src="/create_code_img/" onclick="refresh_check_code(this)">
{# src是url路径,可得到验证码图片,点击时调用refresh_check_code#}
  </div><br></div>

javascript:

<script>
   function refresh_check_code(ths) {
      ths.src += '?';
{# src后面加问好会自动刷新验证码img的src#}
     }
</script>

login的Views

login的Views进行数据验证,然后做相应的处理

post_check_code = request.POST.get('check_code')
session_check_code = request.session['check_code']
if post_check_code.lower() == session_check_code.lower() :
  pass

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python格式化压缩后的JS文件的方法
Mar 05 Python
简单介绍Python中的filter和lambda函数的使用
Apr 07 Python
Python操作MongoDB数据库PyMongo库使用方法
Apr 27 Python
Python实现基于权重的随机数2种方法
Apr 28 Python
python Pandas 读取txt表格的实例
Apr 29 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
Dec 11 Python
python-pyinstaller、打包后获取路径的实例
Jun 10 Python
python按键按住不放持续响应的实例代码
Jul 17 Python
python中的数组赋值与拷贝的区别详解
Nov 26 Python
Python greenlet和gevent使用代码示例解析
Apr 01 Python
Python 生成短8位唯一id实战教程
Jan 13 Python
浅谈tf.train.Saver()与tf.train.import_meta_graph的要点
May 26 Python
Python列表切片用法示例
Apr 19 #Python
Python编程判断这天是这一年第几天的方法示例
Apr 18 #Python
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
Apr 18 #Python
浅析python递归函数和河内塔问题
Apr 18 #Python
Python使用正则表达式实现文本替换的方法
Apr 18 #Python
Python外星人入侵游戏编程完整版
Mar 30 #Python
Python随机数用法实例详解【基于random模块】
Apr 18 #Python
You might like
php 各种应用乱码问题的解决方法
2010/05/09 PHP
php之XML转数组函数的详解
2013/06/07 PHP
详解php中curl返回false的解决办法
2019/03/18 PHP
php和vue配合使用技巧和方法
2019/05/09 PHP
Yii框架布局文件的动态切换操作示例
2019/11/11 PHP
PHP 出现 http500 错误的解决方法
2021/03/09 PHP
javascript中的float运算精度实例分析
2010/08/21 Javascript
淘宝搜索框效果实现分析
2011/03/05 Javascript
dreamweaver 安装Jquery智能提示
2011/04/02 Javascript
JQuery中$之选择器用法介绍
2011/04/05 Javascript
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
2012/05/23 Javascript
JS中如何设置readOnly的值
2013/12/25 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
javascript 数组的定义和数组的长度
2016/06/07 Javascript
jQuery实现的跨容器无缝拖动效果代码
2016/06/21 Javascript
Vue监听数组变化源码解析
2017/03/09 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
微信小程序实现团购或秒杀批量倒计时
2020/11/01 Javascript
vue单页缓存存在的问题及解决方案(小结)
2018/09/25 Javascript
Python读取Excel的方法实例分析
2015/07/11 Python
浅谈python对象数据的读写权限
2016/09/12 Python
Python编程实现双击更新所有已安装python模块的方法
2017/06/05 Python
基于Python中capitalize()与title()的区别详解
2017/12/09 Python
Python程序员面试题 你必须提前准备!
2018/01/16 Python
python实现对象列表根据某个属性排序的方法详解
2019/06/11 Python
TensorFlow tf.nn.conv2d实现卷积的方式
2020/01/03 Python
python中doctest库实例用法
2020/12/31 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
Blue Nile中国官网:全球知名的钻石和珠宝网络零售商
2020/03/22 全球购物
Ruby中的保护方法和私有方法与一般面向对象程序设计语言的一样吗
2013/05/01 面试题
生产现场工艺工程师岗位职责
2013/11/28 职场文书
车间安全生产标语
2014/06/06 职场文书
2015年超市员工工作总结
2015/05/04 职场文书
MySQL infobright的安装步骤
2021/04/07 MySQL
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android