6

トークン隠しフィールドを追加して、ユーザーがフォーラムを二重に送信するのを防ごうとしています。

これが私がこれまでに行ったことです (フォーラムが読み込まれる前に、現在の時刻を値としてトークンを作成するためのこのコードがあります。

$token = time();
setcookie('formToken', $token, time() + 3600);

私のフォーラムには、このような隠し入力があります

<form method="post" action="'.$PHP_SELF.'?action=update">
<input type="hidden" name="token" value="'.$token.'" />
<input type="submit" value="go" />
</form>

$action == "update" のページの上部に、このコードがあります

if(isset($_POST)  &&  ($_POST['token'] != $_COOKIE['formToken'])){
    $error_list .= '<li>You can not submit this forum twise.</li>';
} 

F5 キーを押してページを更新すると、エラーが表示されずにフォームが再度送信されます。

4

7 に答える 7

11

などのフォーラムでも実装されているPRG パターン(Post/Redirect/Get)を使用することをお勧めしますphpbb

Post/Redirect/Get (PRG) は、フォームの送信の重複を防ぎ、ユーザー エージェント (ユーザー) にとってより直感的なインターフェイスを作成する Web 開発デザイン パターンです。PRG は、重複したフォーム送信を作成しない予測可能な方法でブックマークと更新ボタンを実装します。

http://upload.wikimedia.org/wikipedia/commons/3/3c/PostRedirectGet_DoubleSubmitSolution.png

于 2013-03-25T23:58:31.037 に答える
3

フォームが正常に送信されたときにセッションを設定しないのはなぜですか?

そう$_SESSION['submitted'] = 1;

次に、それを確認できます。

またはする

if(isset($_POST['submit'])  &&  ($_POST['token'] != $_COOKIE['formToken'])){
    $error_list .= '<li>You can not submit this forum twice.</li>';
}
于 2013-03-25T23:59:06.343 に答える
0

提案 1)

送信が成功した場合 Cookie を削除します (removeTokens)

    function removeToken()
{
    //set formToken cookie val to "" (or any default xxxx) and the past expiry date for it 
    setcookie("formToken", "", time()-3600);
    //try to unset - this is not needed ,we may try it
    unset($_COOKIE['formToken']);
}

つまり、単にあなたのページで if(isset($_POST)) removeToken();

提案 2)

ここでTom Wrightが提案したようにリダイレクトを実行しますf5を押すときにphpでフォームを再送信しない

 header('Location: formsubmitSucess.php');
于 2013-03-26T00:07:08.950 に答える
0

私はこの方法を使用してフォームの二重送信を防止しています。これまでのところ、すべての場合に機能しています。このチュートリアルは、データベースと PHP に関する中級レベルの知識があることを前提としているため、追加の質問が必要な場合はお知らせください。

ステップ 1 : 次のようにデータベースにフィールドを追加します。YOUR-TABLE をデータベース テーブルの名前に置き換えます。

    ALTER TABLE `YOUR-TABLE` ADD `token` VARCHAR(35) NULL DEFAULT NULL AFTER    `creationtoken`, ADD UNIQUE (`token`) ;

ステップ 2 フォーム ページで、これを最初の行に追加します。クエリとともにデータベース テーブルに挿入される一意のトークンが作成されます。つまり、二重のフォーム送信はありません。

    <?php 
    session_start(); 
    date_default_timezone_set('America/Chicago');
    $_SESSION['token'] = md5(session_id() . time());
    ?>

次に、送信ボタンの直前にこれを追加します。

    // add this before the submit button
    // this will post the unique token to the processing page.

    <div style="width:100%; color:#C00; font-weight:normal;">Session Token: <?php echo strtolower($_SESSION['token']) ?></div>     

    <input type="hidden" name="token" id="token" value="<?php echo  $_SESSION['token']?>" />
    // add this before the submit button


    <input type="submit" id="submit" name="submit" class="button" value="Submit" />

ステップ 3: 今、あなたの process.php ページに

    //this is where all of your form processing takes place.

    // this is where you call the database
    // if you need the database file let me know...
    include("../common/databaseclass.php");
    $db= new database();

    //here the token is posted then the database table is checked and 
    //if the form has already been added it will return a 1 and will 
    //cause the query to die and echo the error message. 

    $token = $_POST['token'];
    $query = "SELECT token FROM YOURTABLE WHERE token = '$token' LIMIT 1";
    $result = $db->query($query);
    $num = mysql_num_rows($result);

    if ($num>0) {die('your form has already been submitted, thank you');}


    else {

    $host = "localhost";
    $user = "user";
    $pass = "password";
    $db_name = "database";

    mysql_connect($host,$user,$pass);
    @mysql_select_db($db_name) or die( "Unable to select database");


    // table query      
    $sql1="INSERT INTO YOURTABLE (
    `token`,
    `user`,
    `email`,
    `password`,
    `newaccount`,
    `zipcode`,
    `city`,
    `state`,
    `country`,
    `telephone`,
    `creationip`,
    `createdaccount`
     ) 
     VALUES (
     '$token',
     '$username',
     '$email',
     '$password',
     '$newaccount',
     '$zipcode',
     '$city',
     '$state',
     '$country',
     '$phone',
     '$ipadress',
     '$createdaccount'

       )";

    $db->query($sql1);
    header("location:" http://home.php ");      

    }
于 2015-02-21T08:54:34.190 に答える