位置: 文档库 > Python > python中django实现验证码的功能实例代码

python中django实现验证码的功能实例代码

在河之洲 上传于 2022-12-03 13:28

《Python中Django实现验证码的功能实例代码》

在Web开发中,验证码是防止恶意攻击(如暴力破解、机器人注册)的重要安全机制。Django作为Python最流行的Web框架之一,提供了灵活的方式实现验证码功能。本文将通过完整实例代码,详细讲解如何在Django项目中集成图形验证码和短信验证码,涵盖生成、验证及前后端交互的全流程。

一、图形验证码实现

图形验证码通过生成包含随机字符的图片,要求用户输入图片中的内容以验证身份。Django中可通过第三方库或自定义实现。

1. 安装依赖库

使用captcha库(推荐)或Pillow+自定义生成:

pip install django-simple-captcha pillow
# 或仅安装Pillow(自定义实现时)
pip install pillow

2. 配置settings.py

若使用django-simple-captcha,需在INSTALLED_APPS中添加:

INSTALLED_APPS = [
    ...
    'captcha',
]

运行迁移命令生成数据库表(如需存储验证码记录):

python manage.py migrate

3. 自定义图形验证码生成器(不依赖第三方库)

创建utils/captcha.py文件,实现验证码图片生成逻辑:

import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from django.core.cache import cache

def generate_captcha(request):
    # 生成随机字符
    chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'  # 排除易混淆字符
    captcha_text = ''.join(random.choices(chars, k=4))
    
    # 创建图片
    image = Image.new('RGB', (120, 40), color=(255, 255, 255))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype('arial.ttf', 28)  # 需确保字体文件存在
    
    # 绘制字符(添加干扰线)
    for i in range(4):
        draw.text((10 + i*25, 5), captcha_text[i], fill=(0, 0, 0), font=font)
    for _ in range(5):
        x1 = random.randint(0, 120)
        y1 = random.randint(0, 40)
        x2 = random.randint(0, 120)
        y2 = random.randint(0, 40)
        draw.line(((x1, y1), (x2, y2)), fill=(0, 0, 0), width=1)
    
    # 将图片转为BytesIO对象
    buffer = BytesIO()
    image.save(buffer, format='PNG')
    captcha_image = buffer.getvalue()
    
    # 存储验证码到缓存(Redis或内存)
    cache_key = f'captcha_{request.session.session_key}'
    cache.set(cache_key, captcha_text.lower(), timeout=300)  # 5分钟有效期
    
    return captcha_image, cache_key

4. 创建验证码视图

views.py中添加生成验证码的视图:

from django.http import HttpResponse
from django.views.decorators.http import require_GET
from .utils.captcha import generate_captcha

@require_GET
def get_captcha(request):
    captcha_image, cache_key = generate_captcha(request)
    response = HttpResponse(content_type='image/png')
    response.write(captcha_image)
    return response

5. 配置URL路由

urls.py中添加路由:

from django.urls import path
from . import views

urlpatterns = [
    path('captcha/', views.get_captcha, name='captcha'),
]

6. 前端集成

在模板中通过img标签加载验证码,并添加刷新按钮:

{% load static %}
验证码

7. 验证码验证逻辑

在表单提交时验证用户输入:

from django.core.cache import cache

def validate_captcha(request):
    user_input = request.POST.get('captcha').lower()
    cache_key = f'captcha_{request.session.session_key}'
    stored_captcha = cache.get(cache_key)
    
    if stored_captcha != user_input:
        return False, '验证码错误'
    cache.delete(cache_key)  # 验证后删除
    return True, '验证通过'

二、短信验证码实现

短信验证码通过发送随机数字到用户手机,常用于注册、登录等场景。需集成第三方短信服务(如阿里云、腾讯云)。

1. 安装短信SDK

阿里云短信服务为例:

pip install aliyun-python-sdk-core aliyun-python-sdk-dysmsapi

2. 创建短信服务工具类

utils/sms.py中封装发送逻辑:

from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
from django.core.cache import cache
import random

class SMSService:
    def __init__(self):
        self.client = AcsClient(
            'your_access_key_id',
            'your_access_key_secret',
            'default'  # 区域ID
        )
    
    def send_sms(self, phone_number):
        code = ''.join(random.choices('0123456789', k=6))
        cache_key = f'sms_{phone_number}'
        cache.set(cache_key, code, timeout=300)  # 5分钟有效期
        
        request = CommonRequest()
        request.set_accept_format('json')
        request.set_domain('dysmsapi.aliyuncs.com')
        request.set_method('POST')
        request.set_protocol_type('https')
        request.set_version('2017-05-25')
        request.set_action_name('SendSms')
        
        request.add_query_param('PhoneNumbers', phone_number)
        request.add_query_param('SignName', '你的签名')
        request.add_query_param('TemplateCode', 'SMS_123456789')  # 模板ID
        request.add_query_param('TemplateParam', f'{{\"code\":\"{code}\"}}')
        
        response = self.client.do_action_with_exception(request)
        return response.decode()  # 返回JSON字符串
    
    def verify_code(self, phone_number, user_input):
        cache_key = f'sms_{phone_number}'
        stored_code = cache.get(cache_key)
        if stored_code != user_input:
            return False
        cache.delete(cache_key)
        return True

3. 创建短信发送视图

from django.http import JsonResponse
from django.views.decorators.http import require_POST
from .utils.sms import SMSService

@require_POST
def send_sms_code(request):
    phone_number = request.POST.get('phone')
    if not phone_number:
        return JsonResponse({'success': False, 'msg': '手机号不能为空'})
    
    sms = SMSService()
    try:
        response = sms.send_sms(phone_number)
        return JsonResponse({'success': True, 'msg': '验证码已发送'})
    except Exception as e:
        return JsonResponse({'success': False, 'msg': str(e)})

4. 配置URL路由

path('send-sms/', views.send_sms_code, name='send_sms'),

5. 前端集成(AJAX示例)






三、验证码安全优化

1. 限制验证码尝试次数:通过缓存记录失败次数,超过阈值后暂时禁用验证。

2. 验证码复杂度:增加字符长度、干扰线、扭曲变形等。

3. 短信频率限制:同一手机号每分钟仅允许发送一次。

4. HTTPS加密:确保验证码传输过程不被窃取。

四、完整示例:注册表单集成验证码

1. 修改注册表单视图:

from django.views.decorators.csrf import csrf_exempt
from .utils.captcha import validate_captcha
from .utils.sms import SMSService

@csrf_exempt
def register(request):
    if request.method == 'POST':
        # 验证图形验证码
        captcha_valid, captcha_msg = validate_captcha(request)
        if not captcha_valid:
            return JsonResponse({'success': False, 'msg': captcha_msg})
        
        # 验证短信验证码(假设已通过其他接口提交)
        phone = request.POST.get('phone')
        sms_code = request.POST.get('sms_code')
        sms = SMSService()
        if not sms.verify_code(phone, sms_code):
            return JsonResponse({'success': False, 'msg': '短信验证码错误'})
        
        # 注册逻辑...
        return JsonResponse({'success': True, 'msg': '注册成功'})

五、常见问题解决

1. 验证码不显示:检查图片生成逻辑是否正确,确保响应头Content-Type: image/png

2. 缓存失效:确认Django缓存配置(如Redis)是否正常运行。

3. 短信发送失败:检查账号权限、模板审核状态及余额。

关键词:Django、验证码、图形验证码、短信验证码、Pillow、阿里云短信、缓存验证Web安全

简介:本文详细介绍了在Django中实现图形验证码和短信验证码的完整流程,包括依赖安装、自定义生成器、前后端交互、安全优化及常见问题解决,提供了可复用的代码示例和最佳实践。