ThinkPHP8验证码通过topthink/think-captcha扩展实现,服务端生成含随机字符的图片并存明文至缓存,校验时比对并立即清除;需安装扩展、启用GD和Session中间件、合理配置captcha.php;API场景返回base64图片与唯一key;校验须取key查缓存、不区分大小写比对、成功后立即清除;建议启用曲线干扰、噪点、精简字符集及调整字号宽度以增强安全性。

ThinkPHP8 的验证码不是内置功能,而是通过 topthink/think-captcha 扩展实现的图形验证机制。它的核心逻辑是:服务端生成一张含随机字符的图片,同时把对应明文(如 "a7F2")安全存入缓存,并将图片返回给前端;用户输入后,后端比对提交值与缓存值是否一致,一致则通过,且立即清除缓存——确保一次性有效。
验证码生成的关键前提
缺一不可,否则 Captcha::create() 返回空白或校验恒失败:
- 执行
composer require topthink/think-captcha安装扩展,确认vendor/topthink/think-captcha目录存在 - 开启 PHP GD 图像扩展(无 GD 则无法绘图)
- 启用 Session 中间件:
\think\middleware\SessionInit::class必须在app/middleware.php中注册 - 检查
config/captcha.php配置合理,例如'length' => 4、'expire' => 1800(30分钟过期)
API 场景下的生成与传输方式
前后端分离项目不能直接用 <img src="/captcha">,需走 API 模式返回 base64 图片和唯一 key:
- 配置
config/captcha.php中'api' => true - 控制器中调用
$imgObj = Captcha::create();,它会返回形如['img' => 'data:image/png;base64,...', 'code' => 'xK9m']的数组 - 生成唯一缓存 key(如
'captcha_' . Uuid::uuid4()),用cache($key, $imgObj['code'], 300)存入(5分钟) - 响应前端:
return success('ok', ['key' => $key, 'img' => $imgObj['img']])
安全校验的三步闭环
校验不是简单比字符串,而是一次性、带绑定、防重放的操作:
立即学习“PHP免费学习笔记(深入)”;
- 从前端表单取两个字段:
input('post.captcha')(用户输入)和input('post.captcha_key')(之前返回的 key) - 用 key 查缓存:
$stored = cache(input('post.captcha_key'));若为null,说明已过期或被清空 - 不区分大小写比对:
strtolower($input) === strtolower($stored);比对成功后立刻cache(input('post.captcha_key'), null)清除
增强防护的实用配置
默认配置易被 OCR 破解,建议在 config/captcha.php 中调整:
-
'useCurve' => true:启用扭曲曲线干扰识别 -
'useNoise' => true:添加噪点,降低图像清晰度 -
'codeSet' => '23456789ABCDEFGHJKLMNPQRSTUVWXYZ':剔除易混淆字符(如 0/O、1/I/l) -
'fontSize' => 28和'imageW' => 130:加大字号与宽度,提升可读性但不牺牲安全性



















