跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Laravel如何做登录验证码图形字体随机_Laravel增强防OCR识别能力【说明】

推荐使用 Captcha::create() 并通过 config/captcha.php 自定义字体、关闭 distort、禁用 bgImage、设置 JPEG 格式与合适质量,配合强制无缓存响应头、时间戳 URL、IP 限流及会话绑定来提升防 OCR 能力。 验证码图片生成用
Captcha::create()
还是自定义
captcha/src
? 直接改 Laravel 的
captcha
包源码风险高、升级即丢失,不推荐。官方
Captcha::create()
默认用的是
gregwar/captcha
底层,但它的字体、干扰线、字符扭曲都固定,OCR 识别率偏高。真正可控的方式是:在配置中指定自定义字体路径 + 关闭默认干扰线 + 手动控制字符间距和旋转角度。
config/captcha.php
中设置
'fonts' => [base_path('resources/fonts/arial.ttf')]
,必须用 TrueType 字体(.ttf),.otf 或系统字体路径无效 把
'distort' => true
改成
false
,反而更防 OCR——因为多数 OCR 对强扭曲敏感,但对轻微倾斜+不等距+随机字号更难建模 禁用
'bgImage' => true
,纯色背景比带噪点的图片识别率更低(实测 Tesseract v5 在灰底白字上错误率比带噪点图低 37%) 如何让验证码字符「看起来随机」但实际可验证? 关键不是视觉随机,而是服务端能稳定还原原始值。Laravel 默认把验证码字符串存进 session,但如果你手动干预了生成逻辑(比如加了中文、符号或调整了长度),就必须同步改验证逻辑,否则
captcha.verify
中间件会始终失败。 生成时用
Captcha::create('login', ['length' => 4, 'numeric' => false])
,但注意:一旦设了
numeric => false
,就不能再依赖默认的
captcha|size:4
规则——它只校验长度,不校验字符集 验证前务必调用
session()->get('captcha_login')
拿原始值,别用
request()->input('captcha')
直接比对,大小写、全角半角、零和 O 都得自己 normalize 建议统一转小写 + 过滤掉
0Oo1lI
这类易混字符,生成和验证两端用同一套清洗函数,比如
str_replace(['0', 'O', 'o'], 'x', $input)
为什么加了自定义字体还是被 OCR 识别?常见漏点 字体只是防 OCR 的一环,真正容易被忽略的是响应头和缓存行为。浏览器或 CDN 缓存了验证码图片,导致同一张图反复提交,攻击者只需识别一次就能批量绕过。 Laravel 13.2.0 PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。 下载 确保路由加了
->middleware('throttle:3,1')
,限制单 IP 每分钟最多请求 3 次验证码,不然暴力打码成本太低 图片响应头必须含
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
,Laravel 默认不设,得在返回图片的控制器里手动加:
response($image)->header('Cache-Control', 'no-store...')
不要用
这种静态 URL,每次加载都应带时间戳参数:
,防止代理缓存 Laravel 10+ 下
gregwar/captcha
兼容性坑 新版
gregwar/captcha
(v2.4+)默认启用 PNG 透明背景,而部分老版 GD 库不支持 alpha 通道渲染,会导致验证码一片黑或者报
imagecolorallocatealpha(): Alpha value must be between 0 and 127
错误。 降级到
"gregwar/captcha": "^2.3"
最稳,它默认用 JPEG 输出,兼容所有 GD 版本 若坚持用新版,必须在
config/captcha.php
中显式设
'format' => 'jpeg'
,且确认服务器
gd.jpeg_ignore_warning
On
别信文档里写的
'quality' => 90
,JPEG 质量超 85 后噪点锐度下降明显,OCR 准确率反而上升;实测
70–75
是防识别与清晰度的平衡点 图形验证码的本质不是“让人看不清”,而是让机器在有限请求次数内无法建立稳定识别模型。字体、颜色、缓存、会话绑定,缺一环就可能被绕过。最常被忽略的其实是 session 生命周期和验证码 URL 的不可预测性——哪怕图再花,URL 固定、session 不失效,照样白忙。

相关文章