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编写一个简单的Lisp解释器的教程
Apr 03 Python
Python中处理字符串之isalpha()方法的使用
May 18 Python
Python实现图像几何变换
Jul 06 Python
Python基于生成器迭代实现的八皇后问题示例
May 23 Python
Python爬取数据并写入MySQL数据库的实例
Jun 21 Python
python 异或加密字符串的实例
Oct 14 Python
python简单验证码识别的实现方法
May 10 Python
python并发编程 Process对象的其他属性方法join方法详解
Aug 20 Python
python实现简单银行管理系统
Oct 25 Python
python词云库wordCloud使用方法详解(解决中文乱码)
Feb 17 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
Mar 13 Python
如何基于python实现年会抽奖工具
Oct 20 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
多重?l件?合查?(一)
2006/10/09 PHP
深入解析Session是否必须依赖Cookie
2013/08/02 PHP
apache php mysql开发环境安装教程
2016/07/28 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
2012/01/15 Javascript
transport.js和jquery冲突问题的解决方法
2015/02/10 Javascript
JavaScript获取表单内所有元素值的方法
2015/04/02 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
jquery实现文本框textarea自适应高度
2016/03/09 Javascript
常用的JQuery函数及功能小结
2016/03/24 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
Vue.js中关于侦听器(watch)的高级用法示例
2018/05/02 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
JS实现的RC4加密算法示例
2018/08/16 Javascript
Vue项目数据动态过滤实践及实现思路
2018/09/11 Javascript
React项目动态设置title标题的方法示例
2018/09/26 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
jQuery弹框插件使用方法详解
2020/05/26 jQuery
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
windows 下python+numpy安装实用教程
2017/12/23 Python
对numpy中布尔型数组的处理方法详解
2018/04/17 Python
Python实现的多项式拟合功能示例【基于matplotlib】
2018/05/15 Python
详解python tkinter模块安装过程
2020/01/06 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
匈牙利最大的健身制造商和销售商:inSPORTline
2018/10/30 全球购物
《盲人摸象》教学反思
2014/02/16 职场文书
幸福家庭标语
2014/06/27 职场文书
股份合作协议书
2014/09/10 职场文书
如何起草一份正确的合伙创业协议书?
2019/07/04 职场文书
python字符串常规操作大全
2021/05/02 Python
一次MySQL启动导致的事故实战记录
2021/09/15 MySQL
Ajax实现异步加载数据
2021/11/17 Javascript
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
2022/04/06 Python
分享一个vue实现的记事本功能案例
2022/04/11 Vue.js