Laravel CSRF中间件默认启用,web路由自动校验,常见419错误源于表单漏@csrf、AJAX未传X-CSRF-TOKEN或session配置异常;豁免需在VerifyCsrfToken的$except中配置URI路径,API路由默认不校验但混用web中间件会重新触发。

CSRF中间件默认就开着,别手贱关掉
新装的 Laravel 项目,web 中间件组默认已包含 VerifyCsrfToken,所有走 web 中间件的 POST/PUT/PATCH/DELETE 请求都会被校验。你不需要额外启用它——反而要小心自己在 app/Http/Kernel.php 里把它从 $middlewareGroups['web'] 里删了,或者在控制器构造函数里写了 $this->middleware('csrf')->except(...) 却没意识到影响范围。
常见错误现象:419 Page Expired 或 TokenMismatchException,往往不是因为没开 CSRF,而是表单漏传 @csrf、AJAX 请求没带 X-CSRF-TOKEN header,或 session 驱动配置异常(比如用 file 但目录不可写,或 Redis 连不上)。
- 检查
config/session.php的driver和对应服务是否正常 - 确保表单里有
@csrf(Blade 模板)或手动输出<input type="hidden" name="_token" value="{{ csrf_token() }}"> - AJAX 请求需在 header 加
X-CSRF-TOKEN: {{ csrf_token() }},Laravel 自带的 Axios 实例已预设该逻辑
排除路由必须用 except 数组,别写错路径格式
需要豁免 CSRF 校验的接口(比如第三方回调、Webhook 接收端),应在 app/Http/Middleware/VerifyCsrfToken.php 的 $except 属性里声明。这里只认「路由 URI 模式」,不认路由名、控制器方法或 HTTP 方法。
使用场景:支付回调(如支付宝异步通知)、微信服务器配置验证、前端调试用的测试接口。
-
$except是字符串数组,每个元素是 URI 路径前缀或完整路径,支持*通配符,例如'api/webhook/*'、'/payment/callback' - 路径不带域名、不带查询参数,也不区分末尾斜杠,
'webhook'和'webhook/'效果一样 - 别写成路由名(如
'webhook.handle')或控制器方法(如'App\Http\Controllers\HookController@handle'),这些完全无效 - 如果用 API 路由(
api中间件组),默认就不走VerifyCsrfToken,无需排除——但这也意味着你得靠sanctum或passport做认证,不能只依赖 session
VerifyCsrfToken 的 tokensMatch 判断逻辑很直接
Laravel 不是比对 token 字符串本身,而是把请求里的 token(来自表单字段 _token 或 header X-CSRF-TOKEN)和 session 里存的 _token 值做严格相等判断。没有加密、没有时间戳、不校验来源 IP 或 User-Agent。
性能影响几乎为零;兼容性上,只要 session 可用、token 未过期(session 生命周期内)、且传输没被截断或编码损坏,就能过。
- 如果你用
redis存 session,确认config/database.php的 redis 配置正确,否则 token 查不到会直接报 419 - 前端若用
fetch发送表单,记得设credentials: 'same-origin',否则 cookie 不带,session 就丢了 - 不要在 JS 里反复调用
{{ csrf_token() }}渲染多个隐藏域——每个请求只需一个有效 token,重复渲染无意义,还可能被误读
API 路由天然绕过 CSRF,但别误以为“安全”
api 中间件组默认不应用 VerifyCsrfToken,这是设计使然:API 应该用 stateless 认证(如 Bearer Token)。但这不代表 API 就自动防 CSRF——如果 API 同时接受 Cookie 认证(比如你手动在 API 路由里加了 auth:sanctum 且前端又发了带 cookie 的请求),那仍可能被 CSRF 利用。
容易被忽略的点:
- 别在 API 路由里混用
web中间件,比如Route::middleware(['api', 'web'])——这会让 CSRF 中间件重新生效,且可能破坏 API 的无状态性 - 如果必须用 Cookie 登录 API(比如 SPA + Sanctum 的登录态),确保前端只在必要时发带 credential 的请求,并用
X-Requested-With: XMLHttpRequest或自定义 header 辅助识别 - 第三方 Webhook 地址一旦加入
$except,就彻底失去 CSRF 防护,务必配合签名验证(如 HMAC)、IP 白名单或临时 token 机制补足安全边界
真正麻烦的从来不是怎么关掉 CSRF,而是关掉之后,你拿什么证明那个请求确实来自你信任的源头。











