laravel使用Blade模板创建提交表单时POST 419 | Page Expired 错误
具体来说,@csrf只需添加。
跨站请求伪造(CSRF)是一种通过伪装授权用户的请求来攻击授信网站的恶意漏洞。
Laravel 通过自带的 CSRF 保护中间件让避免应用遭到跨站请求伪造攻击变得简单:Laravel 会自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,然后将该令牌存放在 Session 中,该令牌用于验证授权用户和发起请求者是否是同一个人。
任何时候在 Laravel 应用中定义 HTML 表单,都需要在表单中引入 CSRF 令牌字段,这样 CSRF 保护中间件才能够对请求进行验证。要想生成包含 CSRF 令牌的隐藏输入字段,可以使用 Blade 指令 @csrf:
<form method="POST" action="/profile"> @csrf ... </form>
中间件组 web 中的中间件 VerifyCsrfToken 会自动为我们验证请求输入的 token 值和 Session 中存储的 token 是否一致,如果没有传递该字段或者传递过来的字段值和 Session 中存储的数值不一致,则会抛出异常。
为了演示该功能,我们在 routes/web.php 中定义一组测试路由:
Route::get('form_without_csrf_token', function (){ return '<form method="POST" action="/hello_from_form"><button type="submit">提交</button></form>'; }); Route::get('form_with_csrf_token', function () { return '<form method="POST" action="/hello_from_form">' . csrf_field() . '<button type="submit">提交</button></form>'; }); Route::post('hello_from_form', function (){ return 'hello laravel!'; });
排除指定 URL 不做 CSRF 安全校验
有时候我们需要从 CSRF 保护中间件中排除一些 URL,例如,如果你使用了第三方支付系统(如支付宝或微信支付)来处理支付并用到他们提供的回调功能,这时候就需要从 Laravel 的 CSRF 保护中间件中排除回调处理器路由,因为第三方支付系统并不知道要传什么 token 值给我们定义的路由。
通常我们需要将这种类型的路由放到文件 routes/web.php 之外,比如 routes/api.php。不过,如果必须要加到 routes/web.php 中的话,你也可以在 VerifyCsrfToken 中间件中将要排除的 URL 添加到 $except 属性数组:
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { /** * 从 CSRF 验证中排除的 URL * * @var array */ protected $except = [ 'alipay/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ]; }
注:运行测试时 CSRF 中间件会自动禁止。