イントロダクション
Laravelでは、クロス・サイト・リクエスト・フォージェリ(CSRF)からアプリケーションを簡単に守れます。クロス・サイト・リクエスト・フォージェリは悪意のあるエクスプロイトの一種であり、信頼できるユーザーになり代わり、認められていないコマンドを実行します。
Laravelは、アプリケーションにより管理されているアクティブなユーザーの各セッションごとに、CSRF「トークン」を自動的に生成しています。このトークンを認証済みのユーザーが、実装にアプリケーションに対してリクエストを送信しているのかを確認するために利用します。
アプリケーションでHTMLフォームを定義する場合は常に、CSRF保護ミドルウェアがリクエストを検証できるように、隠しCSRFトークンフィールドをそのフォームへ含める必要があります。トークンを生成するには、@csrf
Bladeディレクティブが使用できます。
<form method="POST" action="/profile">
@csrf
...
</form>
web
ミドルウェアグループに含まれている、VerifyCsrfToken
ミドルウェアが、リクエスト中のトークンとセッションに保存されているトークンが一致するか、確認しています。
CSRFトークンとJavaScript
JacaScriptで駆動するアプリケーションを構築する場合、JavaScript
HTTPライブラリーに対し、全ての送信リクエストへCSRFトークンを自動的に追加させると便利です。デフォルトでAxios
HTTPライブラリにより、csrf-token
メタタグの値が、resources/assets/js/bootstrap.js
ファイルに登録されます。このライブラリを使用しない場合、自身のアプリケーションでこの振る舞いを用意する必要があります。
URIの除外
一連のURIをCSRF保護より除外したい場合もあります。たとえば、Stripeを課金処理に採用しており、そのWebフックシステムを利用している時、LaravelのCSRF保護よりWebフック処理ルートを除外する必要があるでしょう。なぜならルートに送るべきCSRFトークンがどんなものか、Stripeは知らないからです。
通常、この種のルートはRouteServiceProvider
がroutes/web.php
ファイル中の全ルートへ適用する、web
ミドルウェアから外しておくべきです。しかし、VerifyCsrfToken
ミドルウェアの$except
プロパティへ、そうしたURIを追加することによっても、ルートを除外することができます。
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* CSRFバリデーションから除外するURI
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
Tip!! テスト実行時には、自動的にCSRFミドルウェアは無効になります。
X-CSRF-TOKEN
更に追加でPOSTパラメーターとしてCSRFトークンを確認したい場合は、LaravelのVerifyCsrfToken
ミドルウェアがX-CSRF-TOKEN
リクエストヘッダもチェックします。たとえば、HTML中のmeta
タグにトークンを保存します。
<meta name="csrf-token" content="{{ csrf_token() }}">
meta
タグを作成したら、jQueryのようなライブラリーで、全リクエストヘッダにトークンを追加できます。この手法によりAJAXベースのアプリケーションにシンプルで便利なCSRF保護を提供できます。
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Tip!! デフォルトでAxios HTTPライブラリにより、
csrf-token
メタタグの値が、resources/assets/js/bootstrap.js
へ保持されます。このライブラリを使用しない場合、自分のアプリケーションでこの振る舞いを実現する必要があります。
X-XSRF-TOKEN
LaravelはCSRFトークンをフレームワークにより生成されるリクエストに含まれる、XSRF-TOKEN
クッキーの中に保存します。このクッキーの値をX-XSRF-TOKEN
リクエストヘッダにセットすることが可能です。
いくつかのJavaScriptフレームワークや、AngularとAxiosのようなライブラリーでは、自動的に値をX-XSRF-TOKEN
ヘッダに設定するため、利便性を主な目的としてこのクッキーを送ります。