如何在Django网站中添加验证码?

如何在Django网站中添加验证码?

在Django中添加验证码的目的是为了提高网站的安全性和防止机器恶意攻击。验证码是一种常见的验证方式,它可以在用户注册或登录时要求输入一个随机生成的验证码,以确保登录在用户本人操作下进行,有效地减少了机器恶意攻击的可能性。

对于Django而言,添加验证码主要有两种方式:

  1. 使用第三方库

  2. 自己写Django应用

两种方式各有优劣,下面将详细介绍。

更多Python文章,请阅读:Python 教程

1. 使用第三方库

Django中有很多验证码库,比如django-simple-captcha和django-recaptcha等。这些库已经被很多人使用过,代码较为成熟,可以节省开发时间,提高开发效率。下面以django-simple-captcha为例进行介绍。

首先安装django-simple-captcha:

pip install django-simple-captcha

在settings.py文件中添加以下内容:

# settings.py

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

# 验证码相关参数
# 如果不能正常使用中文的验证码,需要配置字体路径
CAPTCHA_FONT_PATH = 'path/to/fount.ttf'
CAPTCHA_CHINESE_FONT_PATH = 'path/to/fount.ttf'
CAPTCHA_LENGTH = 4 # 验证码长度
CAPTCHA_IMAGE_SIZE = (80, 25) # 验证码图片大小
CAPTCHA_TIMEOUT = 2 # 验证码过期时间(分钟)

在view.py文件中添加以下内容:

# view.py

from django.shortcuts import render
from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url


def register_view(request):
    if request.method == 'GET':
        new_captcha = CaptchaStore.generate_key()
        image_url = captcha_image_url(new_captcha)
        context = {
            'image_url': image_url
        }
        return render(request, 'register.html', context)

    if request.method == 'POST':
        captcha_key = request.POST.get('captcha_0', '')
        captcha_value = request.POST.get('captcha_1', '')
        if CaptchaStore.objects.filter(response=captcha_value, hashkey=captcha_key).exists():
            # 验证码正确,可以进行后续操作
            pass
        else:
            # 验证码错误
            pass

在HTML页面中添加以下内容:

<!-- register.html -->

<form action="" method="POST">
  {% csrf_token %}
  <input type="text" name="username" placeholder="Username">
  <input type="text" name="email" placeholder="Email">
  <input type="text" name="password" placeholder="Password">
  <p>
    <img src="{{ image_url }}" alt="captcha">
    <input type="text" id="id_captcha_1" name="captcha_1" required>
    <input type="hidden" id="id_captcha_0" name="captcha_0" value="{{ new_captcha.hashkey }}">
  </p>
  <input type="submit" value="Register">
</form>

以上代码实现了一个简单的注册页面,包含了一个验证码输入框,当用户提交表单时,会向后端传递验证码值,在后端进行验证。

2. 自己写Django应用

自己写Django应用的好处是可以完全按照自己的需求进行定制,可以实现更加高度的灵活性,同时也可以加深对Django的理解。下面给出自己写验证码应用的代码示例。

首先初始化一个Django应用:

django-admin startapp my_captcha

在my_captcha中创建一个名为captcha.py的文件,包含以下代码:

# captcha.py

import random
from io import BytesIO

from PIL import Image, ImageDraw, ImageFont
from django.http import HttpResponse


class Captcha(object):
    """
    产生随机字符串
    """

    @staticmethod
    def _random_char():
        return chr(random.randint(65, 90))

    """
    产生随机背景颜色
       @staticmethod
    def _random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

    """
    产生验证码图片
    """

    @staticmethod
    def generate_captcha(width=120, height=32, font_size=20, char_length=4):
        # 生成随机字符
        text = ''
        for i in range(char_length):
            text += Captcha._random_char()

        # 生成背景颜色
        color = Captcha._random_color()

        # 生成验证码图片
        image = Image.new('RGBA', (width, height), color)
        font = ImageFont.truetype('path/to/font.ttf', font_size)
        draw = ImageDraw.Draw(image)
        draw.text((10, 10), text, fill=(255, 255, 255), font=font)

        # 输出图片流
        stream = BytesIO()
        image.save(stream, format='JPEG')
        response = HttpResponse(content_type='image/jpeg')
        response.write(stream.getvalue())

        # 返回字符和图片字节流
        return text, response.content

以上代码定义了一个名为Captcha的类,包括了三个方法:生成随机字符,生成随机背景颜色和生成验证码图片。其中generate_captcha方法可以生成一个验证码图片,并返回生成的验证码和图片字节流。

下面在view.py中调用Captcha的generate_captcha方法,向前端返回验证码图片和生成的随机字符。

# view.py

from django.shortcuts import render
from my_captcha.captcha import Captcha


def register_view(request):
    if request.method == 'GET':
        text, image = Captcha.generate_captcha()
        request.session['captcha'] = text
        context = {
            'image': image
        }
        return render(request, 'register.html', context)

    if request.method == 'POST':
        captcha = request.POST.get('captcha', '')
        if captcha.upper() == request.session.get('captcha', '').upper():
            # 验证码正确,可以进行后续操作
            pass
        else:
            # 验证码错误
            pass

以上代码在GET请求时生成验证码图片,并将生成的随机字符保存至session中。在POST请求时,将用户输入的验证码和session中保存的验证码进行比较,以判断是否输入正确。可以看到这种方法的实现和第一种方法基本相同。

最后,在HTML页面中添加以下代码以展示验证码图片和输入框:

<!-- register.html -->

<form action="" method="POST">
  {% csrf_token %}
  <input type="text" name="username" placeholder="Username">
  <input type="text" name="email" placeholder="Email">
  <input type="text" name="password" placeholder="Password">
  <p>
    <img src="data:image/jpeg;base64,{{ image|safe }}">
    <input type="text" id="id_captcha" name="captcha" required>
  </p>
  <input type="submit" value="Register">
</form>

其中的{{ image|safe }}可以将图片字节流转化为base64编码,以展示在HTML页面上。

结论

以上就是在Django网站中添加验证码的两种实现方式,各有优缺点,可以根据自己的需要进行选择。在实际开发中,验证码的实现可以结合Django的各种扩展库,以实现更高效、更灵活的验证码功能。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程