Django实现登录随机验证码的示例代码


Posted in Python onJune 20, 2018

登录验证码是每个网站登录时的基本标配,网上也有很多相应的文章, 但是从生成验证码到 应用到自己的网站上的全步骤,并没有看到很多, 为了节约大家的时间,我把整体步骤写下来, 即拿即用哈

1. 生成随机验证码

#_*_coding:utf-8_*_
from PIL import Image,ImageDraw,ImageFont,ImageFilter
import random
import math, string
#字体的位置,不同版本的系统会有不同
font_path = '/Library/Fonts/Arial.ttf'
#font_path = '/Library/Fonts/Hanzipen.ttc'
#生成几位数的验证码
number = 4
#生成验证码图片的高度和宽度
size = (100,30)
#背景颜色,默认为白色
bgcolor = (255,255,255)
#字体颜色,默认为蓝色
fontcolor = (0,0,255)
#干扰线颜色。默认为红色
linecolor = (255,0,0)
#是否要加入干扰线
draw_line = True
#加入干扰线条数的上下限
line_number = (1,5)

def gen_text():
  source = list(string.ascii_letters)
  for index in range(0,10):
    source.append(str(index))
  return ''.join(random.sample(source,number))#number是生成验证码的位数


#用来绘制干扰线
def gene_line(draw,width,height):
  begin = (random.randint(0, width), random.randint(0, height))
  end = (random.randint(0, width), random.randint(0, height))
  draw.line([begin, end], fill = linecolor)

def gene_code(save_path,filename):
  width,height = size #宽和高
  image = Image.new('RGBA',(width,height),bgcolor) #创建图片

  font = ImageFont.truetype(font_path,25) #验证码的字体和字体大小
  #font = ImageFont.truetype(25) #验证码的字体和字体大小
  draw = ImageDraw.Draw(image) #创建画笔
  #text = "我是中国人" #生成字符串
  text = gen_text() #生成字符串
  print(text)
  font_width, font_height = font.getsize(text)
  draw.text(((width - font_width) / number, (height - font_height) / number),text,\
    font= font,fill=fontcolor) #填充字符串

  if draw_line:
    gene_line(draw, width, height)
    gene_line(draw, width, height)
    gene_line(draw, width, height)
    gene_line(draw, width, height)

  image = image.transform((width + 20, height +10), Image.AFFINE, (1, -0.3, 0, -0.1, 1, 0), Image.BILINEAR) # 创建扭曲
  image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强
  image.save('%s/%s.png' %(save_path,filename)) # 保存验证码图片
  print("savepath:",save_path)
  return text

if __name__ == "__main__":
  gene_code('/tmp','test') #会把生成的图片存成/tmp/test.png

 2. 如何应用到你的django项目中

整个验证码的流程如下
1.用户访问登录页面,你的后台程序在给用户返回登录页面时,同时生成了验证码图片
2.用户输入账户信息和验证码数字,提交表单
3.后台判断用户输入的验证码和你生成的图片信息是否一致,如果一致,就代表验证码是没有问题的

问题就卡在第3步,你在第1步生成验证码并返回给用户后,由于一会用户还需要把这个验证码提交过来,你在后台就需要拿用户输入的和你之前生成 的验证码进行对比是否相等,

所以你必须在生成验证码的同时,把验证码存下来,存到哪? 必然是缓存,这样直接在存的同时加个超时时间 , 就可以限定验证码有效期了。

那存入缓存时的key是设置成什么呢?为了保证验证码的安全,我采取了以下设计

Django实现登录随机验证码的示例代码

3.代码实现

login视图

def acc_login(request):
  err_msg = {}
  today_str = datetime.date.today().strftime("%Y%m%d")
  verify_code_img_path = "%s/%s" %(settings.VERIFICATION_CODE_IMGS_DIR,
                   today_str)
  if not os.path.isdir(verify_code_img_path):
    os.makedirs(verify_code_img_path,exist_ok=True)
  print("session:",request.session.session_key)
  #print("session:",request.META.items())
  random_filename = "".join(random.sample(string.ascii_lowercase,4))
  random_code = verify_code.gene_code(verify_code_img_path,random_filename)
  cache.set(random_filename, random_code,30)

  if request.method == "POST":

    username = request.POST.get('username')
    password = request.POST.get('password')
    _verify_code = request.POST.get('verify_code')
    _verify_code_key = request.POST.get('verify_code_key')

    print("verify_code_key:",_verify_code_key)
    print("verify_code:",_verify_code)
    if cache.get(_verify_code_key) == _verify_code:
      print("code verification pass!")

      user = authenticate(username=username,password=password)
      if user is not None:
        login(request,user)
        request.session.set_expiry(60*60)
        return HttpResponseRedirect(request.GET.get("next") if request.GET.get("next") else "/")

      else:
        err_msg["error"] = 'Wrong username or password!'

    else:
      err_msg['error'] = "验证码错误!"

  return render(request,'login.html',{"filename":random_filename, "today_str":today_str, "error":err_msg})

template文件

{% extends 'base.html' %}
{% block body %}
  <div id="container" class="cls-container">
    <!-- BACKGROUND IMAGE -->
    <!--===================================================-->
    <div id="bg-overlay" class="bg-img img-balloon"></div>
   <!-- HEADER -->
    <!--===================================================-->
    <div class="cls-header cls-header-lg">
      <div class="cls-brand">
        <a class="box-inline" href="index.html" rel="external nofollow" >
          <!-- <img alt="Nifty Admin" src="img/logo.png" class="brand-icon"> -->
          <span class="brand-title">PerfectCRM <span class="text-thin">老男孩教育</span></span>
        </a>
      </div>
    </div>
    <!--===================================================-->
    <!-- LOGIN FORM -->
    <!--===================================================-->
    <div class="cls-content">
      <div class="cls-content-sm panel">
        <div class="panel-body">
          <p class="pad-btm">Sign In to your account</p>
          <form method="post">{% csrf_token %}
            <div class="form-group">
              <div class="input-group">
                <div class="input-group-addon"><i class="fa fa-user"></i></div>
                <input type="text" name="username" class="form-control" placeholder="Username">
              </div>
            </div>
            <div class="form-group">
              <div class="input-group">
                <div class="input-group-addon"><i class="fa fa-asterisk"></i></div>
                <input type="password" name="password" class="form-control" placeholder="Password">
              </div>
            </div>
            <div class="form-group">

              <div class="input-group">

                <div class="input-group-addon">

                  <img height="30px" src="/static/verify_code_imgs/{{ today_str }}/{{ filename }}.png">

                </div>

                <input style="height: 50px" type="text" name="verify_code" class="form-control" placeholder="验证码">

                <input type="hidden" name="verify_code_key" value="{{ filename }}" >

              </div>

            </div>

            <div class="row">

              <div class="col-xs-8 text-left checkbox">

                <label class="form-checkbox form-icon">

                <input type="checkbox"> Remember me

                </label>

              </div>

              <div class="col-xs-4">

                <div class="form-group text-right">

                <button class="btn btn-success text-uppercase" type="submit">Sign In</button>

                </div>

              </div>

            </div>

            {% if error %}

              <span style="color: red">{{ error.error }}</span>

            {% endif %}

          </form>
        </div>
      </div>
     <div class="pad-ver">

        <a href="pages-password-reminder.html" rel="external nofollow" class="btn-link mar-rgt">Forgot password ?</a>

        <a href="pages-register.html" rel="external nofollow" class="btn-link mar-lft">Create a new account</a>

      </div>
    </div>
    <!--===================================================-->

  </div>
  <!--===================================================-->
  <!-- END OF CONTAINER -->
{% endblock %}

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

Python 相关文章推荐
urllib2自定义opener详解
Feb 07 Python
Using Django with GAE Python 后台抓取多个网站的页面全文
Feb 17 Python
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
Sep 28 Python
Python操作Sql Server 2008数据库的方法详解
May 17 Python
python中使用zip函数出现错误的原因
Sep 28 Python
自定义django admin model表单提交的例子
Aug 23 Python
python怎么提高计算速度
Jun 11 Python
pandas创建DataFrame的7种方法小结
Jun 14 Python
keras中epoch,batch,loss,val_loss用法说明
Jul 02 Python
python利用pytesseract 实现本地识别图片文字
Dec 14 Python
史上最详细的Python打包成exe文件教程
Jan 17 Python
Python中的datetime包与time包包和模块详情
Feb 28 Python
python实现Windows电脑定时关机
Jun 20 #Python
python通过微信发送邮件实现电脑关机
Jun 20 #Python
python定时关机小脚本
Jun 20 #Python
Django + Uwsgi + Nginx 实现生产环境部署的方法
Jun 20 #Python
python实现电脑自动关机
Jun 20 #Python
python3将视频流保存为本地视频文件
Jun 20 #Python
Python操作MySQL数据库的方法
Jun 20 #Python
You might like
PHP新手上路(四)
2006/10/09 PHP
使用eAccelerator加密PHP程序
2008/10/03 PHP
深入了解PHP类Class的概念
2012/06/14 PHP
php常见的魔术方法详解
2014/12/25 PHP
php可变长参数处理函数详解
2017/02/22 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
php实现简单的权限管理的示例代码
2017/08/25 PHP
使用Jquery实现每日签到功能
2015/04/03 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
Node.js中用D3.js的方法示例
2017/01/16 Javascript
JS对象创建的几种方式整理
2017/02/28 Javascript
es6函数中的作用域实例分析
2020/04/18 Javascript
[20:46]Ti4循环赛第三日VG vs DK
2014/07/12 DOTA
python实现dict版图遍历示例
2014/02/19 Python
Python常用知识点汇总
2016/05/08 Python
python使用matplotlib库生成随机漫步图
2018/08/27 Python
深入浅析Python2.x和3.x版本的主要区别
2018/11/30 Python
Python 字符串类型列表转换成真正列表类型过程解析
2019/08/26 Python
完美解决Django2.0中models下的ForeignKey()问题
2020/05/19 Python
Python3基于print打印带颜色字符串
2020/07/06 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
你不知道的5个HTML5新功能
2016/06/28 HTML / CSS
html5的画布canvas——画出简单的矩形、三角形实例代码
2013/06/09 HTML / CSS
深入解析HTML5 Canvas控制图形矩阵变换的方法
2016/03/24 HTML / CSS
html5 datalist 选中option选项后的触发事件
2020/03/05 HTML / CSS
台湾网友喜爱的综合型网路购物商城:Yahoo! 奇摩购物中心
2018/03/10 全球购物
大学生创业计划书的用途
2014/01/08 职场文书
全民健身日活动方案
2014/01/29 职场文书
司机检讨书
2014/02/13 职场文书
农村文化活动总结
2014/08/28 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
永远是春天观后感
2015/06/12 职场文书
教育教学读书笔记
2015/07/02 职场文书
歌咏比赛口号大全
2015/12/25 职场文书
公司中层管理培训心得体会
2016/01/11 职场文书
PostgreSQL聚合函数介绍以及分组和排序
2022/04/12 PostgreSQL