Laravel 6のBladeテンプレートで使えるフォーム関係の指令 (@csrf, @method, @error
)

Laravel 6のBladeで使えるフォーム関係の指令の使用方法を記す。
導入
Webアプリケーションでユーザーからの入力データを受け取るために,form
要素を使用する。しかし,form
要素は脆弱性があったり,標準ではGETとPOSTメソッドしか使えなかったり,入力チェックが必要など,これ専用で考慮が必要な点がある。
幸いなことに,PHP Laravel 6のBladeテンプレートには,これらの課題を解消するためのHTMLフォーム専用の指令が3個 (@csrf, @method, @error
) ある。
form
要素をうまく取り扱うために,これらの指令の意味と使用方法を整理した。
@csrf
CSRF (Cross Site Request Forgeries) 攻撃を防ぐための指令となっている。
以下のようにform
要素に@csrf
を配置して使う。
@csrf
の使用方法<form method="POST" action="/home/profile" enctype="multipart/form-data">
@csrf
<textarea name="profile" style="width: 100%; height: 20em;">aa</textarea>
<button class="btn btn-primary">Submit</button>
</form>
実際のHTML上で,@csrf
は以下のinput
要素に変換される。
@csrf
の変換結果<form method="POST" action="/home/profile" enctype="multipart/form-data">
<input type="hidden" name="_token" value="i159n9Y8kzdM19euD527z0y4IuRWqKnIK9qap2IW">
<textarea name="profile" style="width: 100%; height: 20em;">aa</textarea>
<button class="btn btn-primary">Submit</button>
</form>
CSRFは不正なURLをアクセスさせることで,サーバーに処理を誤解させる攻撃となっている。これを防ぐために,フォームページに暗号をhidden
値に仕込み,POSTの受付後にこの暗号を照合することで,不正な要請を弾く。
なお,フォーム内に@csrf
指令の記入を忘れるとHTTP 419が発生し,処理に失敗するので注意する。
@method
HTMLのform
要素でGETとPOST以外のHTTPメソッドを送信するために使用する。
以下のように,form
要素内に@method
指令に使用するHTTPメソッドを引数に指定して使う。
@method
の使用方法<form method="POST" action="/home/profile" enctype="multipart/form-data">
@csrf
@method('PUT')
<textarea name="profile" style="width: 100%; height: 20em;">aa</textarea>
<button class="btn btn-primary">Submit</button>
</form>
実際のHTML上で,@csrf
は以下のname="_method"
属性を持つinput
要素に変換される。
@csrf
の変換結果<form method="POST" action="/home/profile" enctype="multipart/form-data">
<input type="hidden" name="_token" value="i159n9Y8kzdM19euD527z0y4IuRWqKnIK9qap2IW">
<input type="hidden" name="_method" value="PUT">
<textarea name="profile" style="width: 100%; height: 20em;">aa</textarea>
<button class="btn btn-primary">Submit</button>
</form>
HTMLのform
要素のmethod
属性にはGET
とPOST
しか指定することができない。そのため,これら以外のPUT, PATCH, DELETE
メソッドを送信することができない。
@method
指令を使うことでform
要素からこれらのHTTPメソッドを使えるようになる。事前準備として,元々のform
要素のmethod
属性にはPOST
を指定しておく。こうすることで,@method
指令で指定した本来送信したいHTTPメソッドを,hidden
値の_method
パラメーターでHTTPメッセージの本体に仕込むことで,サーバーに伝える。
form
要素からGET
とPOST
以外のHTTPメソッドを使うための必須の方法となる。
@error
@error
は妥当性チェック (バリデーション) の失敗時のエラー表示のための指令となっている。
@error
は単体で使っても意味がなく,妥当性チェックとセットで使って初めて意味がある。
以下のように,妥当性をチェックするパラメーターを引数に指定して使用する。
@error
の使用方法<form method="POST" action="/home">
@csrf
<input name="title" type="text" class="@error('title') is-invalid @enderror">
<button class="btn btn-primary">Submit</button>
</form>
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
妥当性チェックの例は以下となる。
routes/web.php
の妥当性チェックの例Route::post('/home', function(Request $request) {
$request->validate(['title' => 'required'])
return redirect('/home')
});
input
要素に何も入力せずに,ボタンを選択した場合,以下の画面が表示される。
@error
の変換結果<form method="POST" action="/home">
@csrf
<input name="title" type="text" class="is-invalid">
<button class="btn btn-primary">Submit</button>
</form>
<div class="alert alert-danger">The title field is required. </div>
@error
は妥当性チェックとセットで使う指令だ。@error
の引数に指定したパラメーターの妥当性チェック失敗時に,@error...@enderror
で囲んだ部分のコードが有効になる。
$message
変数に妥当性チェックで発生したエラーメッセージが入ってくるので,失敗内容をそのまま表示したい場合にこの変数を使える。なお,この$message
変数の由来が何なのかはドキュメントを探してもわからなかった。
一般的に,form
要素の入力フォームの作成と入力内容のチェックは基本的にセットで行う。妥当性チェックに失敗した場合にユーザーに失敗内容を伝えるために,便利な指令だ。@csrf
と@method
と異なりclass
属性内でも使える。
妥当性チェック失敗時に処理を分岐させる場合に重宝するだろう。
結論
Laravel 6のBladeテンプレートでform
要素をうまく取り扱うの3の指令 (@csrf, @method, @error
) について整理した。
これらの3指令の中では,妥当性チェックの処理が必要な@error
がややとっつきにくくて理解に少々時間がかかった。
どの指令もform
要素を使う上でほぼ必須であるため,今後もform
要素の使用時にこれらの指令をセットで使っていきたい。