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属性にはGETPOSTしか指定することができない。そのため,これら以外のPUT, PATCH, DELETEメソッドを送信することができない。

@method指令を使うことでform要素からこれらのHTTPメソッドを使えるようになる。事前準備として,元々のform要素のmethod属性にはPOSTを指定しておく。こうすることで,@method指令で指定した本来送信したいHTTPメソッドを,hidden値の_methodパラメーターでHTTPメッセージの本体に仕込むことで,サーバーに伝える。

form要素からGETPOST以外の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要素の使用時にこれらの指令をセットで使っていきたい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です