必须执行配置发布、注册中间件到web组、并在表单中添加@honeypot()指令,三者缺一不可;否则防护失效。

直接装就行,但不配中间件和表单字段就等于没装。
composer require spatie/laravel-honeypot 装完必须发布配置
这个包不会自动注册服务提供者(Laravel 8+ 默认支持包自动发现,但配置文件仍需手动发布)。不运行 php artisan vendor:publish --provider="Spatie\Honeypot\HoneypotServiceProvider",config/honeypot.php 就不存在,后续所有自定义(比如字段名、过期时间)都无从谈起。
- 配置文件里
enabled默认是true,但开发环境建议设为false或用app.debug控制,否则本地测试表单总被拦截 -
honeypot_field_name默认是_token—— 注意!这不是 CSRF token 字段,它只是个障眼法名字,实际字段名可任意设(比如website),但必须和你在 Blade 模板里写的保持一致 - 如果改了字段名,记得同步更新中间件和验证逻辑,否则中间件压根收不到值
必须在表单里加 @honeypot() 或手写隐藏字段
Blade 指令 @honeypot() 是最省事的方式,它会自动渲染一个带 CSS 隐藏、且含时间戳的隐藏字段。不加这行,中间件检测不到任何输入,直接放过请求 —— 垃圾机器人照常提交。
- 别只依赖 CSS
display: none,机器人能识别;该指令默认还加了visibility: hidden和position: absolute; left: -9999px多重隐藏 - 字段值不是固定字符串,而是加密时间戳(
encrypt(time())),中间件靠它验是否超时(默认 15 分钟) - 如果你用
form.request验证,得在rules()里显式加'_token' => 'honeypot'(字段名按你配置的来),否则验证器根本不会调用 honeypot 规则
App\Http\Middleware\Honeypot::class 必须注册在 web 中间件组
中间件只对 web 中间件组生效,如果你把它丢进 api 组或全局中间件,要么 404(因为没 session),要么直接报错 Session store not initialized。
- 检查
app/Http/Kernel.php的$middlewareGroups['web']数组,确保\Spatie\Honeypot\Honeypot::class在里面(通常放在\Illuminate\Session\Middleware\StartSession::class之后) - 别把它塞到
$middleware全局数组里——非 web 路由(比如 API)没有 session 支持,中间件一执行就崩 - 如果用了自定义表单提交路径(比如 POST 到
/contact/submit),确认该路由属于web组,否则中间件压根不跑
真正容易漏的是:字段名配置、中间件位置、以及表单里那行 @honeypot() —— 三者缺一,整个防护就形同虚设。没人会告诉你中间件不跑时连日志都不打,只能靠抓包看请求是否被拦住。











