Skip to content

验证码

验证码是防止自动化攻击的重要安全手段。项目使用 django-simple-captcha 库生成图片验证码,存储在数据库中,支持多种验证码格式。源码位于 application/login/views.py

验证码流程

1. 前端请求 GET /login/captcha
2. 后端通过 CaptchaStore.generate_key() 生成验证码
3. captcha_image() 生成图片 -> Base64 编码
4. 返回 {key, captcha} 给前端
5. 前端展示图片,用户输入验证码
6. 登录时后端通过 CaptchaStore 比对验证码

接口说明

获取验证码

GET /login/captcha

响应示例:

json
{
    "code": 0,
    "msg": "操作成功",
    "data": {
        "captcha": "data:image/png;base64,iVBORw0KGgo...",
        "key": 1
    },
    "ok": true
}

后端实现

python
# application/login/views.py
from captcha.models import CaptchaStore
from captcha.views import captcha_image

class CaptchaView(View):
    def get(self, request):
        # 生成验证码密钥
        hashkey = CaptchaStore.generate_key()

        # 从数据库中获取生成的验证码记录ID
        id_key = CaptchaStore.objects.filter(hashkey=hashkey).first().id

        # 生成验证码图片
        image = captcha_image(request, hashkey)

        # 将图片内容转换为Base64编码
        base64_image = base64.b64encode(image.content)
        img_str = "data:image/png;base64," + base64_image.decode("utf-8")

        # 返回验证码图片和密钥
        return R.ok(idkey=id_key, data={"captcha": img_str, "key": id_key})

验证码校验

验证码校验在登录流程中自动完成,通过 django-simple-captcha 内置的表单验证机制:

python
# application/login/forms.py
from captcha.fields import CaptchaField

class LoginForm(forms.Form):
    username = forms.CharField(max_length=30)
    password = forms.CharField(max_length=128)
    captcha = CaptchaField()  # 自动校验验证码

验证码字段

CaptchaField 会自动校验用户输入的验证码是否与数据库中存储的一致,验证成功后自动删除(防重放)。

配置项

settings.py 中配置验证码相关参数:

python
# application/settings.py
INSTALLED_APPS = [
    ...
    'captcha',
]

# 验证码配置
CAPTCHA_IMAGE_SIZE = (160, 50)  # 图片尺寸
CAPTCHA_FONT_SIZE = 28          # 字体大小
CAPTCHA_LETTER_ROTATION = (-35, 35)  # 字符旋转角度
CAPTCHA_NOISE_LINES = 6         # 干扰线数量
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'  # 随机字符
CAPTCHA_LENGTH = 4               # 验证码长度
CAPTCHA_TIMEOUT = 5              # 验证码有效期(分钟)

前端集成

javascript
// 获取验证码
async function getCaptcha() {
    const res = await axios.get('/login/captcha')
    captchaKey.value = res.data.data.key
    captchaImg.value = res.data.data.captcha
}

// 登录时提交
const loginData = {
    username: 'admin',
    password: '123456',
    code: userInput.value,
    key: captchaKey.value
}

总结

验证码方案具备以下特点:

1. django-simple-captcha:成熟的 Django 验证码库,支持多种格式
2. 数据库存储:验证码存储在数据库中,支持过期清理
3. 自动校验:CaptchaField 内置校验逻辑,验证成功后自动删除
4. Base64 传输:图片转 Base64 编码,无需额外的图片访问接口
5. 防重放:验证码一次性使用,验证成功后立即失效

小蚂蚁云团队 · 提供技术支持