下面是关于“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_code
和generate_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技术站