登录界面中图片验证码的生成和校验

一、用pillpw生成图片验证码

1、安装pillow

pip install  pip install pillow

2、下载字体
比如:Monaco.ttf

3、实现生成验证码的方法
该方法返回一个img ,可以把这个img图片保存到内存中,也可以以文件形式保存到磁盘,还返回了验证码的文字。
在app01->utils->code.py, code.py内容如下:

import random
from PIL import Image,ImageDraw,ImageFont,ImageFilter
def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
    code = []
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 写文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    # 写干扰点
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # 写干扰圆圈
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())

    # 画干扰线
    for i in range(5):
        x1 = random.randint(0, width)
        y1 = random.randint(0, height)
        x2 = random.randint(0, width)
        y2 = random.randint(0, height)

        draw.line((x1, y1, x2, y2), fill=rndColor())

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)

验证码的效果如下:
在这里插入图片描述

二、在登录界面加上验证码

1、添加一个验证码的url, 在urls.py 中增加:

from django.urls import path
from app01.views import user,depart,pretty,admin,account

urlpatterns = [
    path('login/account/',account.login),
    path('logout/',account.logout),
    path('image/code/',account.image_code),
]

2、在视图函数中增加验证码的处理
把生成后的图片保存再内存中,返回给页面,验证码的文字要先保存到session中,方便后面根用户输入的验证码进行校验。

from django.shortcuts import render,redirect,HttpResponse
from django import forms
from io import BytesIO
from app01.utils.code import check_code
def image_code(request):

    #调用pillow模块生成验证码
    img,code_string = check_code()

    #将验证码写入到自己的session中,一遍后续获取验证码进行校验
    request.session['image_code'] = code_string
    #给session设置60秒超时
    request.session.set_expiry(60)

    #将图片内容写入到内存中,from io import BytesIO
    stream = BytesIO()
    img.save(stream, 'png')

    return HttpResponse(stream.getvalue())

3、在登录页面增加验证码的输入框

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 400px;
            border-radius: 5px;
            border: 1px solid #dddddd;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }
        .account h2 {
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
<div class="account">
    <h2>用户登录</h2>
      <form  method="post" novalidate>
          {% csrf_token %}
                      <div class="form-group">
                        <label >{{ form.username.label }}</label>
                        {{ form.username}}
                      <span style="color:red">{{ form.username.errors.0 }}</span>
                      </div>
                        <div class="form-group">
                        <label >{{ form.passwd.label }}</label>
                        {{ form.passwd }}
                      <span style="color:red">{{ form.passwd.errors.0 }}</span>
                      </div>
          <div class="form-group">
              <label for="id_code">图片验证码</label>
              <div class="row">
                  <div class="col-xs-7">
                      {{ form.code }}
                      <span style="color: red">{{ form.code.errors.0 }}</span>
                  </div>
                  <div class="col-xs-5">
                      <img id="image_code"  src="/image/code/">
                  </div>
              </div>

          </div>
          <button type="submit" class="btn btn-primary">登录</button>
      </form>



</div>

<script src="{% static 'js/jquery-3.7.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>

登录界面效果如下:
在这里插入图片描述

3、登录的时候对验证码进行校验

获取到用户输入的验证码的值,再从session中取出之前保存的验证码的值,两者比较,如果一致就登录,不一致就重定向到登录界面,提示验证码错误。
还要注意的是,session在生成验证码的时间设置了过期时间是60s, 在登录的时候需要重写设置session的有效期。
在登录的视图函数修改如下:

def login(request):
    """用户登录"""
    if request.method == 'GET':
        form = LoginForm()
        return render(request,'login.html',{'form':form})

    form = LoginForm(data=request.POST)
    if form.is_valid():

        #验证码的校验
        # 这里为什么用pop 是因为cleaned_data获取到的是用户输入的所有信息,包括验证码,但是后面用户名密码根数据库校验的时候验证码是不在数据库的,所以这里就把验证码给去掉
        user_input_code = form.cleaned_data.pop('code')
        code = request.session.get('image_code',"")
        if code.upper() != user_input_code.upper():
            form.add_error("code","验证码错误")
            return render(request,'login.html',{'form':form})

        #print(form.cleaned_data)   #获取到的值是一个字典{'username': 'root', 'passwd': '4233c0d596c55f18df8c99ad1ad8af4f'}
        #校验数据库的用户名和密码
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            form.add_error('passwd','用户名或密码错误')
            return render(request,'login.html',{'form':form})
        #用户名和密码正确
        #网站生成随机字符串; 写到用户浏览器的cookie中,再写入到session中
        request.session['info'] = {'id':admin_object.id,'name':admin_object.username}
        #重新设置session 的有效期,为24小时
        request.session.set_expiry(60*60*24)
        return redirect('/admin/list/')
    return render(request,'login.html',{'form':form})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/69736.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习FreeRTOS】第4章——FreeRTOS任务创建与删除

1.任务创建和删除的API函数 任务的创建和删除本质就是调用FreeRTOS的API函数 动态方式创建任务——xTaskCreate()静态方式创建任务——xTaskCreateStatic()删除任务——vTaskDelete() 动态创建任务&#xff1a;任务的任务控制块以及任务的栈空间所需的内存&#xff0c;均由 F…

Golang函数以及函数和方法的区别

在接触到go之前&#xff0c;我认为函数和方法只是同一个东西的两个名字而已&#xff08;在我熟悉的c/c&#xff0c;python&#xff0c;java中没有明显的区别&#xff09;&#xff0c;但是在golang中者完全是两个不同的东西。官方的解释是&#xff0c;方法是包含了接收者的函数。…

00 - 环境配置

1. 环境说明 使用git gitee 2. 安装配置 ubuntuVM-8-3-ubuntu:~/wuxiang/git$ git --version git version 2.25.1 ubuntuVM-8-3-ubuntu:~/wuxiang/git$2.1 配置user信息 ubuntuVM-8-3-ubuntu:~/wuxiang/git$ git config --global user.name wuxxxxx ubuntuVM-8-3-ubuntu:~…

maven的入门使用

maven的入门使用 1.Maven&#xff08;Maven Apache&#xff09;是一个流行的项目构建和管理工具&#xff0c;2.项目结构和POM文件&#xff1a;3.POM文件&#xff08;Project Object Model&#xff09;4.依赖管理&#xff1a; 在POM文件中5.生命周期和构建过程1.前言2.插件系统3…

Git 入门

一、版本控制 1.1 什么是版本控制 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。简单说就是用于管理多人协同开…

golang协程池库tunny实践

前言 线程池大家都听过&#xff0c;其主要解决的是线程频繁创建销毁带来的性能影响&#xff0c;控制线程数量。 go协程理论上支持百万协程并发&#xff0c;协程创建调度的消耗极低&#xff0c;但毕竟也是消耗对吧。 而且协程池可以做一些额外的功能&#xff0c;比如限制并发&…

【PCIE体系结构十六】PCIE电源管理之ASPM

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考书籍&#xff1a;《PCI.EXPRESS系统体系结构标准教材 Mindshare》 PCIe总线…

面试热题(两数之和)

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答…

STL初探

STL简介 STL(standard template libaray - 标准模板库)是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL的一些版本 原始版本 Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本&#xff0c;…

【UE4 RTS】07-Camera Boundaries

前言 本篇实现的效果是当CameraPawn移动到地图边缘时会被阻挡。 效果 步骤 1. 打开项目设置&#xff0c;在“引擎-碰撞”中&#xff0c;点击“新建Object通道” 新建通道命名为“MapBoundaries”&#xff0c;然后点击接受 2. 向视口中添加 阻挡体积 调整阻挡体积的缩放 向四…

孤立随机森林(Isolation Forest)(Python实现)

目录 1 简介 2 孤立随机森林算法 2.1 算法概述 2.2 原理介绍 2.3 算法步骤 3 参数讲解 4 Python代码实现 5 结果 1 简介 孤立森林&#xff08;isolation Forest&#xff09;是一种高效的异常检测算法&#xff0c;它和随机森林类似&#xff0c;但每次选择划分属性和划…

Zookeeper 面试题

一、ZooKeeper 基础题 1.1、Zookeeper 的典型应用场景 Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架&#xff0c;开发人员可以使用它来进行分布式数据的发布和订阅。 通过对 Zookeeper 中丰富的数据节点进行交叉使用&#xff0c;配合 Watcher 事件通知机…

EFLFK——ELK日志分析系统+kafka+filebeat架构

环境准备 node1节点192.168.40.16elasticsearch2c/4Gnode2节点192.168.40.17elasticsearch2c/4GApache节点192.168.40.170logstash/Apache/kibana2c/4Gfilebeat节点192.168.40.20filebeat2c/4G https://blog.csdn.net/m0_57554344/article/details/132059066?spm1001.2014.30…

设计模式(2)工厂方法模式

一、 1、介绍&#xff1a;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断&#xff0c;根据客户端的选择条件动态实例化相关的类&#xff0c;对于客户端来说…

UML-状态图

目录 状态图 状态图的图符 状态机 状态 ​转换 电话机状态图 活动图和状态图区别&#xff1a; 状态图 状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为&#xff0c;显示了该实体如何根据当前所处的状态对不同的事件做出反应。通常我们创建一个UML状态…

中级课程——CSRF

文章目录 案例原理挖掘 案例 原理 挖掘 挖掘详情 首先就是对目标敏感部位进行抓包分析&#xff0c;比如修改信息、转账、添加信息等等。通常一个数据包HTTP请求头里边都会有一个Referer&#xff0c;这个需要特别去验证。比如放到Burpsuit Repeater里边去测试&#xff1a;去掉…

语音同声翻译软件助你跨越语言障碍

嘿&#xff0c;你在日常工作中是否曾经参加过跨国会议&#xff0c;是否也曾由于语言不通而感到尴尬&#xff1f;别担心&#xff0c;因为现在有了会议实时翻译软件&#xff0c;这些问题都将成为过去式&#xff01;那么你知道会议实时翻译的软件有哪些吗&#xff1f;接下来就让我…

无涯教程-Perl - mkdir函数

描述 此功能使用MODE指定的模式创建一个名称和路径EXPR的目录,为清楚起见,应将其作为八进制值提供。 语法 以下是此函数的简单语法- mkdir EXPR,MODE返回值 如果失败,此函数返回0,如果成功,则返回1。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -w$dirname &…

【计算机视觉|生成对抗】条件生成对抗网络(CGAN)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Conditional Generative Adversarial Nets 链接&#xff1a;[1411.1784] Conditional Generative Adversarial Nets (arxiv.org) 摘要 生成对抗网络&#xff08;Generative Adversarial…

最大子数组和——力扣53

文章目录 题目描述解法一 动态规划题目描述 解法一 动态规划 int maxSubArray(vector<int>& nums){int pre=0, res=nums