Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
512 views
in Technique[技术] by (71.8m points)

php - Preventing duplicate form submissions

I came up with a technique to prevent duplicate form submission by going back/forward or refreshing the page. And I thought about duscussing it here, I already tested a sample not in production environment, what is flaws that you can identify?

Please note that I am well aware of using Form Tokens, which will defend you against CSRF attacks, and wasn't added in the steps below.

-Generate Form ID for each form, and use it as hidden field in the form:

$formid = microtime(true)*10000;

-On form submit:

  • Validate from data

  • Calculate the hash of form fields data

    $allvals = '';
    foreach($_POST as $k=>$v){
        $allvals .= $v;
    }
    $formHash = sha1($allvals);
    
  • Validate form hash by comparing with previously saved hashes. the session value is binded to each form by $formid variable.

    $allowAction = true;
    if(isset($_SESSION['formHash'][$_POST['formid']]) && ($_SESSION['formHash'][$_POST['formid']] == $formHash)){
         $allowAction = false;
    }
    
  • if form hash wasn't found, it means this is the first time form submitted or the form data is changed.
  • If data saved ( to database, for example), save form hash to session:

    $_SESSION['formHash'][$_POST['formid']] = $formHash;
    

Full version of the code: http://thebusy.me/2011/01/06/preventing-duplicate-form-submissions/

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A simpler way to achieve what you want is to use redirect on submit. After you process a POST request you redirect, possibly even to the same page. This is a common pattern called "Redirect after POST" or POST/Redirect/GET.

For example:

<?php
if($_POST) {
    // do something

    // now redirect
    header("Location: " . $_SERVER["REQUEST_URI"]);
    exit;
}
?>

<html> ...
<form method="post" action=""> ... </form>

By setting the action to "" then it will submit to itself, at which point the if($_POST) code block will validate to true and process the form, then redirect back to itself.

Of course you probably want to redirect to a different page that shows a "your form has been submitted" response or put the form on a different page and have the HTML of this page be the response.

The benefit of this method is that when you hit the back button it does a GET request so the form is not re-submitted.

On Firefox, it will actually take the submission to itself out of the browser history so when users browse across the web and then hit back, instead of seeing the "thank you" page they see the form page.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...