4

I have gone through this question, but the answer posted their doesn't solve my problem.

The problem that occurs is that if the user hits the back button of the browser to return to the submitted form, the entered data persists and the user is able to "re-submit" the form. How can I prevent this behaviour (laravel's way)?

my route.php looks like

Route::group(array('after' => 'no-cache'), function()
{
Route::get('/', 'HomeController@index');
Route::ANY('/search','HomeController@search');
Route::get('user/login',array('as'=>'user.login','uses'=>'UserController@getLogin'));
Route::post('user/login',array('as'=>'user.login.post','uses'=>'UserController@postLogin'));
Route::get('user/logout',array('as'=>'user.logout','uses'=>'UserController@getLogout'));
Route::post('user/update/{id}',array('as'=>'user.update','uses'=>'UserController@userUpdate'));
Route::group(array('before' => 'auth'), function()
{
    Route::get('user/profile',array('as'=>'user.profile','uses'=>'UserController@getUserRequest'));
    Route::get('order/checkout','OrderController@checkout');
    Route::get('order/status',array('as'=>'order.status','uses'=>'OrderController@orderStatus'));
    Route::group(array('before' => 'csrf'), function()
    {
        Route::post('order/process','OrderController@process');
    });

});
}); 

filter.php

Route::filter('csrf', function()
{

if (Session::token() != Input::get('_token'))
{
    throw new Illuminate\Session\TokenMismatchException;
}
});
Route::filter('no-cache',function($route, $request, $response){

    header("Cache-Control: no-cache,no-store, must-revalidate"); //HTTP 1.1
    header("Pragma: no-cache"); //HTTP 1.0
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

});

controller code

public function process(){        
    //data is saved to database
    Session::put('_token', md5(microtime())); 
    return Redirect::route('order.status');

}
public function orderStatus(){
    return View::make('orderStatus')->with('message','done');
}
Community
  • 1
  • 1
Trying Tobemyself
  • 3,668
  • 3
  • 28
  • 43
  • are you saying they can press the back button and only 'see' the form - or can they actually submit the form a 2nd time using your code above? – Laurence Jul 25 '13 at 12:03
  • @TheShiftExchange they can submit the form 2nd time. – Trying Tobemyself Jul 25 '13 at 12:18
  • Are you sure you are hitting the process() function? I just ran your code - and it works - I am NOT able to submit twice. Maybe change if (Session::token() != Input::get('_token')) to if (Session::token() != '44444') and see if the forms fails by default? Maybe the route is not being hit? – Laurence Jul 25 '13 at 12:43
  • can you please post your 'form' view file please? – Laurence Jul 25 '13 at 12:45
  • yes its hitting the process() function. [here](http://paste.laravel.com/DBh) is the form view code – Trying Tobemyself Jul 25 '13 at 12:59
  • is it hitting the csrf filter at all? change Session::token() != Input::get('_token')) to if (Session::token() != '44444') and see if the forms fails by default? – Laurence Jul 25 '13 at 13:12
  • and can you please post your FULL process() function? You have commented some of it out? – Laurence Jul 25 '13 at 13:15
  • yes it is hitting csrf filter.. I did what you asked and it throws `Illuminate \ Session \ TokenMismatchException` error.. [here](http://paste.laravel.com/DBw) is the full process() function – Trying Tobemyself Jul 25 '13 at 13:16
  • Are you sure your browser is not 'refreshing' the page when it presses 'back' - because of 'no-cache'? Try this: load the form, view the source, look @ the hidden token code. Then submit the form, press back, and @ look at the hidden token code - are they the same? – Laurence Jul 25 '13 at 13:27
  • no they aren't the same – Trying Tobemyself Jul 25 '13 at 13:32
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34160/discussion-between-trying-tobemyself-rahul-and-the-shift-exchange) – Trying Tobemyself Jul 25 '13 at 13:36

1 Answers1

1

The Shift Exchange:

Are you sure your browser is not 'refreshing' the page when it presses 'back' - because of 'no-cache'? Try this: load the form, view the source, look @ the hidden token code. Then submit the form, press back, and @ look at the hidden token code - are they the same?

Trying Tobemyself Rahu:

no they aren't the same

Then that is your answer! Your browser is 'refreshing' the page when you are pressing 'back'!

So your code 'works' for most browsers - but whichever browser you are using is automatically refreshing the page on the 'back' - thus your token is being repopulated on the form. It is as is the user is 'revisiting' the form - so there is little you can do to stop this. It will work for most browsers...

Or you can turn off the 'no-cache' for the form - or set it to like 5mins or something - so the browser will not refresh the page.

Maybe have a 'form' cache filter - which is 5mins and a filter for all the other site - which is 0, something like that would be 'Laravel elegant' :)

Laurence
  • 58,936
  • 21
  • 171
  • 212