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牛刀小试密码爆破
Feb 03 Python
深入解析Python编程中super关键字的用法
Jun 24 Python
轻量级的Web框架Flask 中模块化应用的实现
Sep 11 Python
python处理DICOM并计算三维模型体积
Feb 26 Python
对Python中TKinter模块中的Label组件实例详解
Jun 14 Python
python实现网站用户名密码自动登录功能
Aug 09 Python
PYTHON EVAL的用法及注意事项解析
Sep 06 Python
深入浅析Python科学计算库Scipy及安装步骤
Oct 12 Python
python 发送json数据操作实例分析
Oct 15 Python
python算的上脚本语言吗
Jun 22 Python
Django+Uwsgi+Nginx如何实现生产环境部署
Jul 31 Python
python​格式化字符串
Apr 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
收音机术语解释
2021/03/01 无线电
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
php中mkdir函数用法实例分析
2014/11/15 PHP
php文件上传类完整实例
2016/05/14 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
PHP实现根据密码长度显示安全条
2017/07/04 PHP
你的编程语言可以这样做吗?
2006/09/07 Javascript
HTML页面登录时的JS验证方法
2014/05/28 Javascript
JavaScript中的闭包介绍
2015/03/15 Javascript
js简单实现竖向tab选项卡的方法
2015/05/04 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
JS解决iframe之间通信和自适应高度的问题
2016/08/24 Javascript
AngularJS实现星星等级评分功能
2016/09/24 Javascript
angularjs中使用ng-bind-html和ng-include的实例
2017/04/28 Javascript
详解webpack2+React 实例demo
2017/09/11 Javascript
Vue核心概念Getter的使用方法
2019/01/18 Javascript
JS实现判断有效的数独算法示例
2019/02/25 Javascript
如何进行微信公众号开发的本地调试的方法
2019/06/16 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
vue 使用外部JS与调用原生API操作示例
2019/12/02 Javascript
vue pages 多入口项目 + chainWebpack 全局引用缩写说明
2020/09/21 Javascript
Element-UI 使用el-row 分栏布局的教程
2020/10/26 Javascript
Python实现的简单dns查询功能示例
2017/05/24 Python
python生成多个只含0,1元素的随机数组或列表的实例
2018/11/12 Python
Python File(文件) 方法整理
2019/02/18 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
Python实现区域填充的示例代码
2021/02/03 Python
HTML4和HTML5之间除了相似以外的10个主要不同
2012/12/13 HTML / CSS
Clarks鞋美国官网:全球领军鞋履品牌
2017/05/13 全球购物
纽约著名的服装辅料来源:M&J Trimming
2017/07/26 全球购物
Diesel美国网上商店:意大利牛仔时装品牌
2020/12/10 全球购物
银行员工犯错检讨书
2014/09/16 职场文书
公司放假通知范文
2015/04/14 职场文书
初中美术教学反思
2016/02/17 职场文书
教你用Python写一个植物大战僵尸小游戏
2021/04/25 Python