Laravel - CSRF
路由篇中我们已经讲过了 POST - PUT - DELTE 请求的时候需要使用到 CSRF。
在前端的模板中,我们可以使用以下方式来生成 CSRF.
[ Blade 中使用CSRF ]
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
blade模板会自动为我们完成这件事情。
[ META 中使用CSRF ]
除了可以在表单中使用,还可在Meta中添加 CSRF
<meta name="csrf-token" content="{{ csrf_token() }}">
一旦创建了 meta
标签,你就可以使用类似 jQuery 的库将令牌自动添加到所有请求的头信息中。这可以为您基于 AJAX 的应用提供简单、方便的 CSRF 保护。
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
填写在meta中,很适合单页程序使用,vue ,NG,之类的单页应用。
[ 关于CSRF白名单 ]
CSRF 是由中间件所控制的。在 App\Http\kernel.php 文件中, 我们可以看到
<?php
...
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
...
?>
这里说明所有使用了 web中间件的文件,都会触发CSRF中间件。如果你不需要使用CSRF中间件,那就不要让你的路由排除在web中间件之外。
当然也有其他方法。我们可以在 VerifyCsrfToken.php 中添加除外路由。
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//指定路由不使用CSRF验证
];
}
?>
当然也可以另一种方式,修改 handle 方法。可以更加灵活,还可以做逻辑处理。
<?php
namespace App\Http\Middleware;
//添加Closure引用,否则会报错
use Closure;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//指定路由不使用CSRF验证
];
public function handle($request, Closure $next)
{
//如果路由是 example7. 那就不检测
if ( ! $request->is('example7'))
{
return parent::handle($request, $next);
}
return $next($request);
}
}