简介
CSRF(Cross-Site Request Forgery)是一种冒充已登录用户,让其发送非本人意图请求的攻击。 例如,你的应用有一个POST /user/email 接口,用于修改邮箱地址。如果攻击者在另一个网站上放置了自动向该 URL 提交的表单,那么用户可能在毫无察觉的情况下被修改了邮箱。
在 Laravel 13 中,由于 web 中间件组已内置相关机制,CSRF 保护默认处于启用状态。
防御 CSRF 攻击
Laravel 的PreventRequestForgery 中间件通过以下两个层面防御 CSRF:
- Origin 校验(
Sec-Fetch-Site头) - 令牌校验(会话级 CSRF 令牌)
Origin 校验
Laravel 首先检查Sec-Fetch-Site,判断请求是否来自同一 Origin。这在 HTTPS 环境下尤其有效。
若 Origin 校验通过,则该请求会被直接放行。若未通过,则会像以往那样执行 CSRF 令牌校验。
Origin-only 模式
你可以禁用令牌校验的回退,仅通过 Origin 校验来判断。403 而不是 419。
如果你希望允许同站请求(例如跨子域请求),可以设置 allowSameSite。
令牌校验
Laravel 会为每个会话生成 CSRF 令牌。可以通过csrf_token() 或会话获取。
web 路由中创建 POST、PUT、PATCH、DELETE 表单时,务必包含 @csrf。
排除 URI
对于像 Stripe Webhook 这样由外部服务发来的请求,有时需要将特定 URI 从 CSRF 保护中排除。如果可能,请将 Webhook 路由放在
web 中间件组之外,并将排除设置控制在最小范围。X-CSRF-TOKEN 头
Laravel 不仅会校验表单中的_token,也会校验 X-CSRF-TOKEN 头。
首先,将令牌输出到 meta 标签。
X-XSRF-TOKEN 头
Laravel 还会发送加密过的XSRF-TOKEN Cookie。Axios 或 Angular 在发送同源请求时,会自动将该值设置到 X-XSRF-TOKEN 头中。
因此,在 SPA 或 AJAX 实现中,某些情况下即使不手动编写请求头设置,CSRF 保护也能生效。