LoginSignup
3

More than 3 years have passed since last update.

51歳からのプログラム 備忘 リロードによる二重投稿

Last updated at Posted at 2019-05-20

休みの日に、簡単なチャットアプリを作ったのだけれど、リロードによる二重投稿に嵌ったよ。制作中のアプリにも搭載する予定の機能なので、備忘必須。

二重投稿の防止

laravelのグローバルなsessionヘルパを使います。

・ blade.phpから、乱数をpostでcontrollerに送信し、sessionにも登録しておく。
・ controller側では、受信したpostの値と、sessionの値を比較して、両者が異なっていたら処理を中断する。

sam1
<?php
//if(!(session_start()) { session_start(); }

  try{ session_start();}catch(Exception $ex){}

$token = rand();
session(['token'=>$token]);
?>

<form action="/sam2" method="post">
{{csrf_field()}}
  <input type="text" name="name">

  // 目印を POSTで送信する                                     
  <input type="hidden" name="token" value="<? echo $token ?>">
</form>
controller
public function sam2(Request $request)
{
  //if(!session_start()){ session_start(); }

  try{ session_start(); }catch(Exception $e){}

   // 同値判定
   // セッションの目印と、POST送信された目印が同じかどうか判定
   try
   {
       if($_POST['token'])
       {
           if($_POST['token']==session('token'))
           {
               session(['token'=>'']);

               // formされた情報に、必要な処理をする
           }
       }
    }catch(Exception $e){}
}

controllerのtry-catch

unset処理に関して

上記ではsession(['token'=>'')として初期化しているが、グローバルヘルパではなく、グローバルセッションを使う場合、\$_SESSION['pass'] と \$_POST['pass'] の同値判定をした後に、リロードや連続投稿を防止するために、\$_SESSION(若しくは\$_POST)をunsetするが、高速リロード、高速連続投稿の時には、unset後、すぐに同じ同値判定を行おうとして、unsetした\$_SESSION(若しくは\$_POST)を評価し、undefineエラーが投げつけられることがあった。これを回避するためにtryで処理したら大丈夫だった!

同値判定を関数にして風通しよくする

controller
public function ReceiveForm(){
  $result = $this->sessionCheck($request);
  if( $result == "" ){ return false; }

  // 処理

}

function sessionCheck($request){
  try{ session_start() }catch(Exception $e){}
  try{ if( session('token') ){
           if( session('token') === $_POST['token'] ){
               $form = $request->all();
               session(['token'=>'');
               unset($form['_token']); // これはcsrf_field()のtokenを削除してる
               unset($form['token]);   // これはPOST送信されてきたtokenを削除してる
               return $form;
           }
  }catch(Exception $e){}
  $form=[];
  return $form;
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3