django项目登录中使用图片验证码的实现方法

yizhihongxing

下面是关于“Django项目登录中使用图片验证码的实现方法”的完整攻略,包含以下几个步骤:

步骤一:安装必要的Python库

使用图片验证码需要安装Pillow库,可以使用pip来安装,命令如下:

pip install pillow

步骤二:生成随机验证码

我们可以使用Python的Pillow库来生成一张随机的图片验证码:

import random
from PIL import Image, ImageDraw, ImageFont

def generate_random_code(length=4):
    # 生成指定长度的随机验证码
    return ''.join(random.sample('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', length))

def generate_code_image(code, width=120, height=50):
    # 生成指定大小的验证码图片
    font_path = 'path/to/your/image/font.ttf'  # 需要提供一个字体文件路径
    font = ImageFont.truetype(font_path, size=36)
    image = Image.new('RGB', (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    for x in range(width):
        for y in range(height):
            draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
    for i in range(len(code)):
        draw.text((20 * i + 10, 10), code[i], font=font, fill=(255, 0, 0))
    return image

步骤三:将验证码图片显示在登录页面

我们可以在登录页面中加入一个<img>标签来显示验证码图片,同时将随机生成的验证码放入session中,以便在提交表单的时候校验验证码是否正确。

<form method="post">
  {% csrf_token %}
  <input type="text" name="username">
  <input type="password" name="password">
  <input type="text" name="code">
  <img src="/captcha/" alt="验证码">
  <input type="submit" value="登录">
</form>

其中,/captcha/是一个Django视图函数的URL,将会匹配到下面的视图函数。

步骤四:编写Django视图函数

import io
from django.shortcuts import render, HttpResponse
from .utils import generate_random_code, generate_code_image

def captcha(request):
    # 生成随机验证码
    code = generate_random_code(length=4)
    # 生成验证码图片字节流
    img = generate_code_image(code)
    buffer = io.BytesIO()
    img.save(buffer, format='jpeg')
    # 将验证码存入session中
    request.session['captcha'] = code
    # 返回验证码图片给浏览器
    return HttpResponse(buffer.getvalue(), content_type='image/jpeg')

上面的代码中,generate_random_codegenerate_code_image是之前生成随机验证码和验证码图片的函数,captcha是一个Django视图函数,用于返回生成的验证码图片,同时将验证码保存到session中。

提交登录表单时,需要校验输入的验证码是否正确。可以在登录视图函数中加入如下代码:

def login(request):
    if request.method == 'POST':
        # 先校验验证码
        code = request.POST.get('code')
        if code != request.session.get('captcha'):
            return HttpResponse('验证码错误!')
        # 处理登录请求
        ...
    else:
        return render(request, 'login.html')

上面的代码中,request.POST.get('code')获取用户输入的验证码,request.session.get('captcha')获取之前存储的验证码,如果两者不一致则返回错误信息。

示例说明一:在Django Admin中添加图片验证码

我们可以在django.contrib.admin模块中注册一个自定义的登录视图,来实现在Django Admin中添加图片验证码的功能:

from django.contrib.admin import site, AdminSite
from django.contrib.auth.views import LoginView
from django.urls import path
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
from .utils import generate_random_code, generate_code_image

class CaptchaAdminSite(AdminSite):
    login_template = 'admin/login_with_captcha.html'

    @never_cache
    def login(self, request, extra_context=None):
        code = generate_random_code(length=4)
        img = generate_code_image(code)
        buffer = io.BytesIO()
        img.save(buffer, format='jpeg')
        request.session['captcha'] = code
        response = HttpResponse(buffer.getvalue(), content_type='image/jpeg')
        response['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
        response['Pragma'] = 'no-cache'
        return response

    @method_decorator(never_cache)
    def index(self, request, extra_context=None):
        return super().index(request, extra_context=extra_context)

captcha_admin_site = CaptchaAdminSite(name='captchadmin')

上面的代码中,CaptchaAdminSite是一个自定义的AdminSite,我们重写了其login方法,在其中生成验证码图片,保存到session中,然后返回验证码图片。

同时,我们还需要创建一个修改后的Django Admin的登录模板admin/login_with_captcha.html,以便在其中引入验证码图片:

{% extends "admin/login.html" %}

{% block head %}
  {{ block.super }}
  <style>
    #captcha {
      cursor: pointer;
    }
  </style>
{% endblock %}

{% block body %}
  <h1>{% trans 'Log in' %}</h1>
  <form method="post" action="{% url 'admin:login' %}">
    {% csrf_token %}
    {% if form.non_field_errors %}
      <div class="alert alert-danger">{{ form.non_field_errors }}</div>
    {% endif %}
    <div class="form-group{% if form.username.errors %} has-danger{% endif %}">
      {{ form.username.label_tag }}
      {{ form.username }}
      {% if form.username.errors %}
        <div class="form-control-feedback">{{ form.username.errors }}</div>
      {% endif %}
    </div>
    <div class="form-group{% if form.password.errors %} has-danger{% endif %}">
      {{ form.password.label_tag }}
      {{ form.password }}
      {% if form.password.errors %}
        <div class="form-control-feedback">{{ form.password.errors }}</div>
      {% endif %}
    </div>
    <div class="form-group">
      {{ form.captcha.label_tag }}
      {{ form.captcha }}
    </div>
    <hr>
    <input type="submit" class="btn btn-primary" value="{% trans 'Log in' %}">
  </form>
  <p id="captcha">{{ _('Click to Refresh') }}</p>
{% endblock %}

{% block extrajs %}
  {{ block.super }}
  <script>
    $('#captcha').on('click', function() {
      $('img.captcha').attr('src', '/admin/login/captcha/?_=' + Math.random());
    });
  </script>
{% endblock %}

在模板中我们添加了一个<img>标签,用于显示验证码图片,同时也添加了一个点击事件,使得在点击验证码图片时可以通过AJAX重新加载新的验证码。

上面的代码中,{% if form.captcha.errors %} has-danger{% endif %}{{ form.captcha }}用于在表单中添加验证码输入框,同时校验验证码是否正确。

最后,我们需要将修改后的Django Admin的URL映射到之前定义的CaptchaAdminSite上:

from django.contrib.admin import site
from .admin import captcha_admin_site

site = captcha_admin_site

示例说明二:使用django-simple-captcha库

django-simple-captcha是一个Django的一个第三方库,提供了方便易用的图片验证码功能,我们可以使用这个库来快速实现图片验证码。

首先,需要安装django-simple-captcha库:

pip install django-simple-captcha

然后在Django项目中添加captcha应用,并在INSTALLED_APPS中添加captcha应用:

INSTALLED_APPS = [
    # ...
    'captcha',
    # ...
]

接下来,需要在urls.py中添加如下URL映射:

from captcha.views import captcha_refresh

urlpatterns = [
    # ...
    path('captcha/', captcha_refresh, name='captcha'),
    # ...
]

最后,我们需要在登录视图函数中添加django-simple-captcha所提供的验证码校验功能:

from captcha.fields import CaptchaField
from captcha.helpers import captcha_image_url

class LoginForm(forms.Form):
    username = forms.CharField(max_length=30)
    password = forms.CharField(widget=forms.PasswordInput)
    captcha = CaptchaField()

def login(request):
    form = LoginForm(request.POST or None)
    if form.is_valid():
        # 处理登录请求
        ...
    return render(request, 'login.html', {'form': form})

上面的代码中,我们使用了django-simple-captcha所提供的CaptchaField字段,用于在表单中添加图片验证码输入框。同时,在模板中使用{% captcha_image %}标签,以便在浏览器中显示验证码图片。

至此,我们已经完成了图片验证码的实现方法说明,可以根据以上步骤加入图片验证码功能到自己的Django项目中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django项目登录中使用图片验证码的实现方法 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python 代码实现列表的最小公倍数

    首先需要了解“最小公倍数”的概念。最小公倍数,指的是一个数既是若干数的倍数,且是它们之中最小的那个数。比如,4和6的最小公倍数是12,因为4×3=12,6×2=12。 然后需要了解“列表”的概念。列表是Python中的一种数据类型,它由一系列有序元素组成,可以包含任何类型的数据。列表可以用方括号([])来创建,元素之间用逗号分隔。 接下来,我们可以通过编写P…

    python 2023年6月3日
    00
  • 如何在Python中使用Flask SQLAlchemy操作数据库?

    如何在Python中使用Flask SQLAlchemy操作数据库? Flask SQLAlchemy是一个基于Flask的Python ORM(对象关系映射)库,它提供了一种简单的方式来操作关系型数据库。使用Flask SQLAlchemy,我们可以使用Python代码来创建、读取、更新删除关系型数据库中的数据。以下是如何在Python中使用Flask S…

    python 2023年5月12日
    00
  • 十行Python3代码实现去除pdf文件水印

    下面是详细的讲解: 1.了解pdf水印的实现原理 pdf文件中的水印通常是通过使用页眉来添加的。页眉可以包含文字和图片等内容,也可以用于添加水印。 因此,我们要删除一个pdf文件中的水印,就需要找到包含水印的页眉,然后从页眉中删除水印内容。 2.使用Python3代码去除pdf文件水印的步骤 步骤如下: 安装Python的pdf包pypdf2。可以使用命令:…

    python 2023年6月3日
    00
  • Python 函数基础知识汇总

    Python函数基础知识汇总 什么是函数? 在Python中,函数是一段代码块,用于执行特定的任务。函数接受输入,并在一些处理之后返回输出。 函数可以让我们编写可重用代码,避免重复编写相同的代码。同时,函数的使用也使得代码看起来更加简洁易懂。 如何定义函数? 在Python中,定义函数非常简单。使用def关键字,指定函数名称以及输入参数,就可以定义一个函数了…

    python 2023年5月13日
    00
  • python乱序字符串排序的实现方式

    下面是关于Python乱序字符串排序的完整攻略: 1. 什么是乱序字符串排序 乱序字符串排序,指的是对由任意个字符串元素组成的字符串进行排序。这个排序可以按照不同的规则来进行,如按照字典序升序排列、按照字符串长度升序排列等。 2. 乱序字符串排序的实现方式 下面介绍两种基于Python语言的乱序字符串排序的实现方式: 2.1 使用sorted函数实现 通过P…

    python 2023年6月3日
    00
  • 深入理解python try异常处理机制

    深入理解Python中的try异常处理机制 异常处理是编程中非常重要而且必不可少的一环,Python语言中使用try、except、finally语句块来捕获、处理异常,这个机制是Python程序中最基础、最常用、最重要的机制之一。在本篇文章中,我们将会深入探讨Python中的try异常处理机制,了解其常用的语法形式、捕获的多种异常类型、异常处理的流程以及常…

    python 2023年5月13日
    00
  • 让 python 命令行也可以自动补全

    为了让Python命令行也支持自动补全,我们需要使用第三方库readline和rlcompleter。下面是完整的攻略过程,其中包含了两条示例说明。 安装readline和rlcompleter 在终端中执行以下命令安装readline: sudo apt-get install libreadline-dev 在终端中执行以下命令安装rlcompleter…

    python 2023年5月19日
    00
  • Python async模块使用方法杂谈

    Python async模块使用方法杂谈 Python async(协程)是近年来非常流行的一种异步编程模式。async通过事件循环机制和协程技术实现其非阻塞的异步效果,让我们能够更方便、高效地编写异步代码。在本文中,我们将详细讲解Python async模块的使用方法,并带有两个示例说明。 1.异步编程概述 在传统的编程模式中,当程序执行到一个耗时的I/O…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部