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 相关文章推荐
python基础教程之自定义函数介绍
Aug 29 Python
Python urllib、urllib2、httplib抓取网页代码实例
May 09 Python
pytorch + visdom 处理简单分类问题的示例
Jun 04 Python
python 画三维图像 曲面图和散点图的示例
Dec 29 Python
15行Python代码实现网易云热门歌单实例教程
Mar 10 Python
Python中常用的8种字符串操作方法
May 06 Python
Python和Java的语法对比分析语法简洁上python的确完美胜出
May 10 Python
python实现车牌识别的示例代码
Aug 05 Python
Python如何把多个PDF文件合并代码实例
Feb 13 Python
python实现简单的购物程序代码实例
Mar 03 Python
Python包资源下载路径报404解决方案
Nov 05 Python
还在手动盖楼抽奖?教你用Python实现自动评论盖楼抽奖(一)
Jun 07 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
德生PL660的电路分析和打磨
2021/03/02 无线电
分页详解 从此分页无忧(PHP+mysql)
2007/11/23 PHP
php实现的通用图片处理类
2015/03/24 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
2019/10/10 PHP
PHP代码覆盖率统计详解
2020/07/22 PHP
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
jquery实现鼠标滑过小图时显示大图的方法
2015/01/14 Javascript
javascript将数字转换整数金额大写的方法
2015/01/27 Javascript
JSON格式的键盘编码对照表
2015/01/29 Javascript
javascript常用函数(1)
2015/11/04 Javascript
纯js仿淘宝京东商品放大镜功能
2017/03/02 Javascript
关于bootstrap日期转化,bootstrap-editable的简单使用,bootstrap-fileinput的使用详解
2017/05/12 Javascript
es6+angular1.X+webpack 实现按路由功能打包项目的示例
2017/08/16 Javascript
jQuery自动或手动图片切换效果
2017/10/11 jQuery
jQuery实现输入框的放大和缩小功能示例
2018/07/21 jQuery
深入理解Python中命名空间的查找规则LEGB
2015/08/06 Python
编写Python爬虫抓取暴走漫画上gif图片的实例分享
2016/04/20 Python
Python的Flask框架中配置多个子域名的方法讲解
2016/06/07 Python
基于python socketserver框架全面解析
2017/09/21 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
Python3多进程 multiprocessing 模块实例详解
2018/06/11 Python
python通过zabbix api获取主机
2018/09/17 Python
Python3.5迭代器与生成器用法实例分析
2019/04/30 Python
浅谈pyqt5在QMainWindow中布局的问题
2019/06/21 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
python 爬取古诗文存入mysql数据库的方法
2020/01/08 Python
CSS书写规范、顺序和命名规则
2014/03/06 HTML / CSS
澳大利亚领先的在线美容商店:Facial Co
2017/10/22 全球购物
anello泰国官方网站:日本流行包包品牌
2019/08/08 全球购物
OLEDBConnection和SQLConnection有什么区别
2013/05/31 面试题
会计求职信怎么写
2015/03/20 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
Golang: 内建容器的用法
2021/05/05 Golang
JavaScript前端面试组合函数
2022/06/21 Javascript