Django使用Django Simple Captcha实现登录验证码

一.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中创建验证码信息。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容