gregwar/captcha 是 Laravel 里最稳的验证码方案,因其不依赖 session 驱动、生成快、兼容 GD/Imagick/纯文本、Laravel 5.5+ 开箱即用,且路由与验证解耦、配置灵活、性能影响小。

为什么 gregwar/captcha 是 Laravel 里最稳的验证码方案
它不依赖 session 驱动(默认用文件,但可配 Redis),生成快、无 GD 扩展强依赖(fallback 到 imagick 或纯文本),且 Laravel 5.5+ 开箱即用。其他包要么强制要求 php-gd,要么把路由和验证逻辑耦合进中间件,改起来反而是坑。
常见错误现象:Class 'Gregwar\Captcha\CaptchaBuilder' not found —— 多半是没执行 composer autoload-dump,或用了 Laravel 10+ 却装了老版本(需用 ^2.4)。
- 安装命令必须带版本约束:
composer require gregwar/captcha:^2.4 - Laravel 9/10 用户注意:不要用
^1.0,它不兼容 PHP 8.1+ 的返回类型声明 - 如果项目开了 OPCache,装完记得
php artisan config:clear再试
怎么在表单里嵌入动态验证码并校验
核心就两步:前端显示图片 + 后端比对 session 里的 hash 值。它不走数据库,也不需要额外字段,captcha 中间件只是帮你生成并存 session,校验靠 captcha 规则。
使用场景:登录页、注册页、密码重置页——只要需要防机器提交,就直接加 captcha 字段和规则。
- Blade 模板里插入:
<img src="{{ captcha_src('default') }}" onclick="this.src='{{ captcha_src('default') }}?'+Math.random()" alt="captcha"> - 表单提交字段名必须叫
captcha(否则规则不生效) - 验证规则写法:
'captcha' => 'required|captcha',不是captcha:default - 别手动
session()->put()覆盖_captcha键,会破坏校验逻辑
captcha_src() 返回 404 或图片打不开怎么办
本质是路由没注册成功,或者响应头被中间件污染。这个函数输出的是一个临时 URL,指向 /captcha/default 这类路径,背后由 Gregwar\Captcha\CaptchaServiceProvider 自动注册路由。
性能影响很小:每次请求只生成一张图,缓存策略由浏览器控制,服务端不存图文件。
- 检查
config/app.php是否漏掉了Gregwar\Captcha\CaptchaServiceProvider::class(Laravel 5.5+ 可省略,但 5.4 或手动禁用了 auto-discovery 就必须加) - 确认
APP_DEBUG=true时访问/captcha/default能看到图;如果返回 404,运行php artisan route:list | grep captcha看有没有对应路由 - Nginx 下如果用
try_files,要确保没把/captcha/路径误判为静态资源而拦截
自定义字体、尺寸、过期时间的关键参数在哪改
所有配置都集中在 config/captcha.php,运行 php artisan vendor:publish --provider="Gregwar\Captcha\CaptchaServiceProvider" 才会生成。改完必须清配置缓存:php artisan config:clear。
容易踩的坑:字体路径写相对路径(如 fonts/arial.ttf)会失败,必须用绝对路径,推荐用 resource_path('fonts/arial.ttf')。
-
'width' => 120和'height' => 46控制图片尺寸,太小易被 OCR 识别,太大拖慢首屏 -
'expire' => 60是 session 中验证码 hash 的存活秒数,不是图片 URL 过期时间 -
'length' => 4表示字符数,设为 6 以上会显著增加用户输入错误率,不建议盲目加长 - 若用 Redis 存 session,确保
SESSION_DRIVER=redis,否则captcha规则永远报错
复杂点在于多语言站点:它默认只支持拉丁字母+数字,中文需自己替换字体并重写 generate() 方法,这时候不如换 anerg/captcha——但那是另一个权衡了。


















