IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【Django】开发日报_9_Day:手机号码管理系统(7) -> 正文阅读

[Python知识库]【Django】开发日报_9_Day:手机号码管理系统(7)

图片验证码显示与校验

为了防止被人暴力破解。所以要在登陆界面添加验证功能。

1、验证码显示
(1)图片验证码

login.html

<!--图片验证码-->
        <div class="form-group">
            <label for="id_code">图片验证码</label>
            <div class="row">
                <div class="col-xs-7">
                    <input type="text" name="code" class="form-control" placeholder="请输入图片验证码" required=""
                           id="id_code">
                    <span style="color: red;"></span>
                </div>
                <div class="col-xs-5">
                    <img id="image_code" src="{% static '/img/code.png/' %}" style="width: 100px">
                </div>
            </div>
        </div>

自备一张
在这里插入图片描述
访问页面
在这里插入图片描述
上面只是搭建了一个静态案例,下面学习如何用代码生成图片。

(2)生成图片

安装第三方模块:pip install pillow
使用方法

导入字体文件,并拷贝到项目文件夹
在这里插入图片描述

C:\Windows\Fonts
在这里插入图片描述
新建测试代码

from PIL import Image,ImageDraw,ImageFont
img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
#创建画笔
draw = ImageDraw.Draw(img, mode='RGB')
#导入字体文件
font = ImageFont.truetype("FZSTK.TTF",20)
#写文字
draw.text([0,0],'代码骑士',"red",font=font)
# 保存在本地
with open('code.png','wb') as f:
    img.save(f,format='png')

显示图片:
在这里插入图片描述
生成验证码函数
转载

from PIL import Image,ImageDraw,ImageFilter,ImageFont

import random

def check_code(width=120, height=30, char_length=5, font_file='ALGER.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)

if __name__ == '__main__':
    # 1. 直接打开
     img,code = check_code()
     #img.show()
     print(code)
     # 保存在本地
     with open('code.png', 'wb') as f:
        img.save(f, format='png')
(3)项目实例

1、创建一个url保存图片
urls.py

#------------------图片验证码---------------------------------------------------
    path('image/code/', account.image_code),

2、在登陆页面中引入图片
login.html
在这里插入图片描述
3、在app01中utils创建code文件
code.py

from PIL import Image,ImageDraw,ImageFilter,ImageFont

import random

def check_code(width=120, height=30, char_length=5, font_file='ALGER.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)

4、在视图函数中调用生成随机验证码图片的函数

from app01.utils.code import check_code
#将图片写入内存
from io import BytesIO

def image_code(request):
    """生成图片验证码"""
    #调用生成图片函数
    img,code_string = check_code()
    print(code_string)
    #将图片对象img写入内存
    stream = BytesIO()
    img.save(stream,'png')
    return HttpResponse(stream.getvalue())

5、在中间件中取消对保存图片url的访问
auth.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render

class AuthMiddleware(MiddlewareMixin):
    """中间件"""
    def process_request(self,request):
        #0、排除不需要登录验证就能访问的页面
        if request.path_info in ["/login/","/image/code/"]:
            return
        #1、读取当前访问的用户的session信息,如果能读到,说明已登录过,就可以继续向后走
        info_dict = request.session.get("info")
        if info_dict:
            return
        # 2、没登录过,重新登录
        return redirect("/login/")

6、访问页面
在这里插入图片描述

2、验证码校验
(1)项目实例

1、先将随机验证码的字符串写到用户session中

account.py

def image_code(request):
    """生成图片验证码"""
    #调用生成图片函数
    img,code_string = check_code()
    #print(code_string)

    #将随机验证码写入session中,便于后续校验
    request.session['image_code'] = code_string
    #给session设置60s超时,超时则验证码无效
    request.session.set_expiry(60)

    #将图片对象img写入内存
    stream = BytesIO()
    img.save(stream,'png')
    return HttpResponse(stream.getvalue())

2、修改form字段
form.py

class LoginForm(BootStrapForm):#采用继承
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,#(attrs={'class':"form-control",'placeholder':'用户名'})
        required=True#必填项
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),#render_value=True:保留原来字段#(attrs={'class':"form-control",'placeholder':'密码'})
        required=True#必填项
    )
    code = forms.CharField(
        label="用户名",
        widget=forms.TextInput,
        required=True#必填项
    )
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)

3、修改登陆逻辑
account.py

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():
        #print(form.cleaned_data)
        #{'username': '111', 'password': '111','code':111}
        #{'username': '111', 'password': '70a53ebb8836a4400fe2827ab6cc86bf','code':'xxx' }

        #验证码校验
        #user_input_code = form.cleaned_data["code"]
        #获取用户输入的验证码并从数据字典中拿掉,防止影响下面的用户验证
        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})

        #去数据库进行校验,获取用户对象、None
        #admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'],password=form.cleaned_data['password']).first()
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        #用户名为空
        if not admin_object:
            form.add_error("password","用户名或密码错误")
            return render(request, 'login.html', {'form': form})
        #用户名和密码正确
        #网站随机生成字符串,写到用户浏览器的cookie中,在写入到session中
        request.session["info"] = {'id':admin_object.id,'name':admin_object.username}
        return redirect("/admin/list/")
    return render(request,'login.html',{'form':form})

4、修改前端页面
login.html

<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/" style="width: 100px">
                </div>
            </div>
        </div>

5、访问页面
在这里插入图片描述
在这里插入图片描述
***6、延长有session效时间,实现七天免登陆
在这里插入图片描述

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:49:11  更:2022-09-30 00:50:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 3:23:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计