最省事方案是直接安装gregwar/captcha包,它稳定兼容laravel 9/10,避免自行实现gd/imagick带来的安全与识别风险;常见报错多因未执行vendor:publish或未清缓存。

laravel 用 gregwar/captcha 最省事
直接装这个包,不是 Laravel 自带的,但社区维护稳定、文档清晰、Laravel 9/10 都能跑。别折腾自己写 GD 或 imagick 图形生成逻辑——容易出安全漏洞,也难防 OCR 和自动识别。
常见错误现象:Captcha::create() 报错找不到类,或验证码图片返回 500;多数是没执行 php artisan vendor:publish,或者缓存没清。
- 安装命令:
composer require gregwar/captcha - 发布配置:
php artisan vendor:publish --provider="Gregwar\Captcha\CaptchaServiceProvider" - 路由加中间件前先确认
session已启用(config/session.php中driver不为array) - 生成验证码时别用
captcha/src这种硬路径——用Captcha::src()方法,它自动处理 URL 和缓存键
Laravel 表单里怎么嵌入并校验图形验证码
核心就两步:前端显示图片 + 后端验证输入值。关键不是“怎么显示”,而是“怎么防止绕过”——比如没校验 session ID 是否匹配,或把验证码明文塞进 hidden 字段传给前端。
使用场景:登录页、注册页、密码重置页,凡是有机器人暴力提交风险的地方。
- 视图中插入图片:
<img src="%7B%7B%20captcha_src('default')%20%7D%7D" onclick="this.src='{{ captcha_src('default') }}?'+Math.random()" alt="Captcha"> - 表单必须带
@csrf,且提交时传captcha字段(名字不能改,除非你重写了验证规则) - 控制器里验证写法:
$request->validate(['captcha' => 'required|captcha'])—— 注意这个captcha规则来自扩展包,不是 Laravel 原生的 - 别在验证失败后直接
return back()就完事,要调用Captcha::reset(),否则同一张图可能被反复提交多次
为什么验证码总提示“Incorrect captcha”
八成不是代码写错了,而是 session 或缓存没对上。这个错误信息来自 CaptchaValidator 的 fails 判断,本质是比对当前请求里的 captcha 值和 session 里存的哈希值是否一致。
参数差异:默认配置下,验证码文本存在 session 的 captcha/default 键里;如果你改了 config/captcha.php 中的 session_key,但没同步改验证逻辑,就会失配。
- 检查
config/captcha.php里的expire值是否太小(单位秒),设成 600 比较稳妥 - 确认
APP_URL和实际访问域名一致,否则跨域时 cookie 不带 session_id - 用
dd(session('captcha'))看 session 里有没有存进去,没有就说明生成环节中断了(比如响应被中间件截断、输出了额外空格) - 别在 API 路由里用这个包——它强依赖 session,而无状态 API 应该用 token-based 验证(如 SMS 或邮箱一次性码)
图形验证码真能防住攻击吗
不能。现在主流爬虫基本不碰图形验证码了,要么用打码平台(几毛钱一次),要么直接调用 OCR 接口(tesseract 对简单干扰线识别率超 80%)。它真正防的是低级脚本和批量注册,不是专业攻击者。
性能影响很小,但兼容性要注意:如果用户禁用 cookie,整个机制就失效;另外某些国内安卓 WebView 会拦截 data: 协议图片(captcha_src 默认用 base64 输出时),得强制走 URL 模式。
- 生产环境建议关掉
debug模式,否则错误堆栈可能泄露captchasession key 结构 - 别把验证码当成唯一防线——配合 IP 限流(
throttle:5,1)、邮箱/手机二次确认,才构成基础防护层 - 如果业务敏感度高(如金融类操作),图形验证码该换就得换,比如用
hCaptcha或行为分析 SDK,而不是修修补补
最难调的其实是干扰线密度和字体旋转角度——调得太狠用户看不清,调得太松机器一扫就过。这玩意儿没银弹,只能按实际日志里失败率+用户投诉率来回试。










