一.Django Simple Captcha的安装与配置
- 安装:
pip3 install django-simple-captcha
-
配置:
在settings.py中需要配置INSTALLED_APPS、TEMPLATES和DATABASES:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
# 添加验证码功能
'captcha',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
-
验证码功能配置
Django Simple Captcha设有多种验证码的生成方式,如设置验证码的内容、图片噪点和图片大小等,这些功能可以在(site-packages\captcha\cong\settings.py)中的源码内自行查看。
以下只是举例:
"""
MyDjango的settings.py
Django Simple Captcha的基本配置
设置验证码的显示顺序
一个验证码识别包含文本输入框,隐藏域和验证码图片
"""
# CAPTCHA_OUTPUT_FORMAT是设设置三者的显示顺序
CAPTCHA_OUTPUT_FORMAT = '%(text_field)s %(hidden_field)s %(image)s'
# 设置图片噪点
CAPTCHA_NOISE_FUNCTIONS = (
# 设置样式
'captcha.helpers.noise_null',
# 设置干扰线
'captcha.helpers.noise_arcs',
# 设置干扰点
'captcha.helpers.noise_dots',
)
# 图片大小
CAPTCHA_IMAGE_SIZE = (100, 25)
# 设置图片背景颜色
CAPTCHA_BACKGROUND_COLOR = '#ffffff'
# 图片中的文字为随机英文字母
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
# 图片中的文字为英文单词
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.word_challenge'
# 图片中的文字为数字表达式
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
# 设置字符个数
CAPTCHA_LENGTH = 4
# 设置超时时间(minutes)
CAPTCHA_TIMEOUT = 1
- 完成上述配置后,下一步执行数据迁移,因为验证码需要依赖数据表才能实现
二.使用验证码实现用户登录
完成Django Simple Captcha与MyDjango的功能搭建,下一步在用户登录页面实现验证码功能。
- 用户登录页面:由表单生成,表单类在项目应用user的forms.py中定义。
- 登录验证:触发POST请求,用户信息以及验证功能由Django内置的Auth认证系统实现。
- 验证码动态刷新:由Ajax向Captcha功能应用发送GET请求完成动态刷新。
- 验证码动态验证:由Ajax向Django发送GET请求完成验证码验证。
# user的forms.py
# 定义用户登录表单类
from django import forms
from captcha.fields import CaptchaField
class CaptchaTestForm(forms.Form):
username = forms.CharField(label='用户名')
password = forms.CharField(label='密码', widget=forms.PasswordInput)
captcha = CaptchaField()
#MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(('user.urls', 'user'), namespace='user')),
path('captcha/', include('captcha.urls'))
]
# user的urls.py
from django.urls import path
from .views import *
urlpatterns = [
# 用户登录界面
path('', loginView, name='login'),
path('ajax_val', ajax_val, name='ajax_val'),
]
# user的views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate
from .forms import CaptchaTestForm
# 用户登录
def loginView(request):
if request.method == 'POST':
form = CaptchaTestForm(request.POST)
# 验证表单数据
if form.is_valid():
u = form.cleaned_data['username']
p = form.changed_data['password']
if User.objects.filter(username=u):
user = authenticate(usernme=u, password=p)
if user:
if user.is_active:
login(request, user)
tips = '登陆成功'
else:
tips = '账号密码错误,请重新输入'
else:
tips = '用户名不存在,请注册'
else:
form = CaptchaTestForm()
return render(request, 'user.html', locals())
# ajax接口,实现动态验证码验证
from django.http import JsonResponse
from captcha.models import CaptchaStore
def ajax_val(request):
if request.is_ajax():
# 用户输入的验证码结果
r = request.GET['response']
# 隐藏域的value值
h = request.GET['hashkey']
cs = CaptchaStore.objects.filter(response=r, hashkey=h)
# 若存在cs,则验证成功,否则验证失败
if cs:
json_data = {'status': 1}
else:
json_data = {'status': 0}
return JsonResponse(json_data)
else:
json_data = {'status': 0}
return JsonResponse(json_data)
# templates的user.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css">
</head>
<body>
<div class="flex-center">
<div class="container">
<div class="flex-center">
<div class="unit-1-2 unit-1-on-mobile">
<h1>MyDjango Verification</h1>
{% if tips %}
<div>{{ tips }}</div>
{% endif %}
<form class="form" action="" method="post">
{% csrf_token %}
<div>用户名:{{ form.username }}</div>
<div>密码:{{ form.password }}</div>
<div>验证码:{{ form.captcha }}</div>
<button type="submit" class="btn btn-primary btn-block">确定</button>
</form>
</div>
</div>
</div>
</div>
<script>
$(function () {
// ajax 刷新验证码
$('.captcha').click(function () {
console.log('click');
$.getJSON("/captcha/refresh",function (result) {
$('.captcha').attr('src', result['image_url']);
$('#id_captcha_0').val(result['key'])
});
});
// ajax动态验证验证码
$('#id_captcha_1').blur(function () {
// #id_captcha_1 为输入框的id
// 该输入法失去焦点就会触发函数
json_data = {
// 获取输入框和影藏字段id_captcha_0的数值
'response':$('#id_captcha_1').val(),
'hashkey':$('#id_captcha_0').val()
}
$.getJSON('/ajax_val', json_data,function (data) {
$('#captcha_status').remove()
// 若status返回1,则验证码正确
// 若status返回0,则验证码错误
if(data['status']){
$('#id_captcha_1').after('<span id="captcha_status">*验证码正确</span>')
}else{
$('#id_captcha_1').after('<span id="captcha_status">*验证码错误</span>')
}
});
});
})
</script>
</body>
</html>
至此,运行MyDjango,访问127.0.0.1:8000即可看到带验证码的用户登录页面。单击图片验证码将触发Ajax请求,Django动态刷新验证码图片,并在数据表captcha_captchastore中创建验证码信息。