如何在Django网站中添加验证码?
在Django中添加验证码的目的是为了提高网站的安全性和防止机器恶意攻击。验证码是一种常见的验证方式,它可以在用户注册或登录时要求输入一个随机生成的验证码,以确保登录在用户本人操作下进行,有效地减少了机器恶意攻击的可能性。
对于Django而言,添加验证码主要有两种方式:
- 使用第三方库
-
自己写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的各种扩展库,以实现更高效、更灵活的验证码功能。