laravel 9 中应通过 verifycsrftoken 中间件的 $except 数组豁免特定路由(如 'api/'、'webhook/'),而非全局禁用或控制器中处理;api 路由组(routes/api.php)默认已跳过 csrf 验证。

在 Laravel 9 中,表单提交默认需携带 CSRF token,否则会返回 419 错误。但某些接口无法提供 token(如第三方回调、定时任务触发的 POST、API 入口等),必须跳过验证——不能靠前端“伪造空 token”,也不能在控制器里写 `except()`,因为 CSRF 中间件在路由调度前就已执行。
推荐方式:在 VerifyCsrfToken 中间件中配置 $except
这是最规范、最安全的做法。编辑 app/Http/Middleware/VerifyCsrfToken.php 文件,在 $except 数组中添加需豁免的路径:
- 支持单层通配符 *,例如
'api/*'匹配/api/users,但不匹配/api/v1/users - 多层路径可写成
'api/*/*'或逐条列出,如'webhook/stripe'、'pay/notify' - 不支持正则表达式,Laravel 内部用的是
Str::is()做前缀匹配 - 典型需排除的路径包括:
/api/*、/webhook/*、/pay/notify、/admin/import
临时方案:用 Route::withoutMiddleware() 单独绕过
适合极个别动态路由或调试场景。例如:
Route::post('/debug/test', [DebugController::class, 'handle']) ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
- 仅对该路由生效,不影响其他逻辑
- 生产环境必须加注释说明原因,避免被误认为安全疏漏
- 注意:若该路由还受 auth 等中间件保护,跳过 CSRF 不影响身份校验,但语义上已削弱防护层级
哪些路由本就不用管?Laravel 默认已豁免
Laravel 9 的 api 路由组(注册在 routes/api.php)默认不启用 session,也不走 VerifyCsrfToken 中间件,所以天然跳过 CSRF 验证。
- 同理,
_ignition(错误页面)、telescope(监控面板)等系统路径也自动豁免 - 关键点在于:是否属于
web中间件组。如果一个 API 路由被错误地定义在routes/web.php中,它就会被套上 web 组,此时仍需手动加入$except
绝对不要做的两件事
- 不要在 Kernel.php 中注释掉整个 VerifyCsrfToken 中间件:这等于全局关闭 CSRF,严重削弱应用安全性
-
不要在控制器构造函数或方法里调用
$this->middleware('csrf')->except(...):CSRF 校验发生在路由解析阶段,控制器代码根本不会运行到那一步











