Laravel 5.7 で二重送信対策
フォームなどの更新が伴うようなページで、予期しない複数回のリクエストに対応するよう Laravel 5.7 で対策を行ってみます。
二重送信などの複数回リクエスト対策
重複したリクエストが発生するケースとして、次のものが考えられます。
- サブミットボタンをダブルクリックする。
- 戻るボタンで戻って、再度サブミットボタンを押す。
- 完了ページでリロードする。
- CSRF攻撃によるリクエスト。
Laravel では、クロス・サイト・リクエスト・フォージェリ( CSRF )対策を行わないと 419 エラーが返されます。この対策に使用されているトークンを利用することで二重送信の対策を行います。
<?php
namespace App\Http\Controllers;
use App\Mail\Contact;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Requests\ContactRequest;
class ContactController extends Controller
{
//
public function send(Request $request){
$contact = $request->all();
Mail::to('hogehoge@gmail.com')->send(new Contact($contact));
// 二重送信対策
$request->session()->regenerateToken();
return 'メッセージを送信しました。';
}
}
Laravel では、VerifyCsrfToken ミドルウェアがリクエスト中のトークンとセッションに保存されているトークンが一致するか確認するので、処理が完了した時点でトークンを再生成します。これにより重複したリクエストが発生した場合、トークンが一致しなくなりエラーとして処理されます。
トークンを再生成している部分は次のようになります。
// 二重送信対策
$request->session()->regenerateToken();
戻るボタンで戻って、再度サブミットボタンを押してみると 419 エラーが返され二重で送信されないことを確認できます。