简介

Laravel 提供了简单的方法使你的应用免受 跨站请求伪造 (CSRF) 的袭击。跨站请求伪造是一种恶意的攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令。

Laravel 为每个活跃用户的 Session 自动生成一个 CSRF 令牌。该令牌用来核实应用接收到的请求是通过身份验证的用户出于本意发送的。

任何情况下在你的应用程序中定义 HTML 表单时都应该包含 CSRF 令牌隐藏域,这样 CSRF 保护中间件才可以验证请求。辅助函数 php csrf_field 可以用来生成令牌字段:

  1. <form method="POST" action="/profile">
  2. {{ csrf_field() }}
  3. ...
  4. </form>

包含在 php web 中间件组里的 php VerifyCsrfToken 中间件会自动验证请求里的令牌 php token 与 Session 中存储的令牌 php token 是否匹配。

CSRF 令牌和 Vue

如果你使用 Vue.js 框架,没有 php make:auth 命令提供的身份验证过渡,那么你需要在你应用的主要布局中手动定义一个 php Laravel Javascript对象。这个对象会指定 Vue 在做请求时需要的 CSRF 令牌:

  1. <script>
  2. window.Laravel = {!! json_encode([
  3. 'csrfToken' => csrf_token(),
  4. ]) !!};
  5. </script>

CSRF 白名单

有时候你可能希望设置一组并不需要 CSRF 保护的 URI。例如,如果你正在使用 Stripe 处理付款并使用了他们的 webhook 系统,你会需要将 Stripe webhook 处理的路由排除在 CSRF 保护外,因为 Stripe 并不知道发送给你路由的 CSRF 令牌是什么。

一般地,你可以把这类路由放到 php web 中间件外,因为 php RouteServiceProvider 适用于 php routes/web.php 中的所有路由。不过如果一定要这么做,你也可以将这类 URI 添加到 php VerifyCsrfToken 中间件中的 php $except 属性来排除对这类路由的 CSRF 保护:

  1. <?php
  2. namespace App\Http\Middleware;
  3. use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
  4. class VerifyCsrfToken extends BaseVerifier
  5. {
  6. /**
  7. * 这些 URI 会被免除 CSRF 验证
  8. *
  9. * @var array
  10. */
  11. protected $except = [
  12. 'stripe/*',
  13. ];
  14. }

X-CSRF-TOKEN

除了检查 POST 参数中的 CSRF token 外,php VerifyCsrfToken 中间件还会检查 php X-CSRF-TOKEN 请求头。你可以将令牌保存在 HTML php meta 标签中:

  1. <meta name="csrf-token" content="{{ csrf_token() }}">

一旦创建了 php meta 标签,你就可以使用类似 jQuery 的库将令牌自动添加到所有请求的头信息中。这可以为您基于 AJAX 的应用提供简单、方便的 CSRF 保护。

  1. $.ajaxSetup({
  2. headers: {
  3. 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  4. }
  5. });

X-XSRF-TOKEN

Laravel 将当前的 CSRF 令牌存储在由框架生成的每个响应中包含的一个php XSRF-TOKEN cookie 中。你可以使用该令牌的值来设置 X-XSRF-TOKEN 请求头信息。

这个 cookie 作为头信息发送主要是为了方便,因为一些 JavaScript 框架,如 Angular,会自动将其值添加到 php X-XSRF-TOKEN 头中.