
お問い合わせフォームへの連投を防ぐ方法+α
Category PHP
Date 2012年10月03日

お問い合わせフォームに何の対策もしていないと、完了画面でブラウザの更新(F5)を押した時にメールが2通飛んでしまう、といったことが起こります。
それを防ぐ為のプログラミングの仕方に関して、メモ的にエントリーします。
何も対策をしていないと、いたずらにあった場合に大変なことに
特に意識せずにプログラミングしている場合、こんな感じになると思います。<?php /*----- 入力フォーム -----*/ // 何もなし ?> <form action="ex1_end.php" method="POST"> <textarea name="note">お問い合わせっぽいもの</textarea> <textarea name="note">実際は送信しないよ</textarea> <input type="submit" name="submitBtn" value="送信!" /></form>
<?php /*----- 完了画面 -----*/ // 送信処理を記述 ?> 送信されました!
サンプルを準備しましたので、確認してみてください。
サンプル1
【送信!】ボタンを押すと、完了画面に移動します。
実際にメールは私の方に飛んできませんので、安心して押しまくってください。
その後、完了画面でブラウザの更新(F5)を押すと、次の画面が出てきます。
(画面はFirefox)

ここで【再送信】を押すと、何も対策をしていなければ再度メールが飛びます。
ブラウザの更新(F5)を押せば押すほど、何回でも出来てしまいますので、メール送信の機能をつけていたら私のメールボックスが大変なことになってしまいます。
連投されないための対策
そこで、対策をしたものが次のサンプルです。サンプル2
一見同じに見えますが、完了画面にてブラウザの更新(F5)を押し、【再送信】してみてください。
画面に表示されるメッセージが「失敗しました」に変わると思います。
プログラムとしては、次のように記述しています。
<?php /*----- 入力フォーム -----*/ // セッション開始 session_start(); // タイムスタンプと推測できない文字列にてキーを発行 $key = md5(time()."推測できない文字列"); // 発行したキーをセッションに保存 $_SESSION['key'] = $key; ?> <form action="ex2_end.php" method="POST"> <textarea name="note"> お問い合わせっぽいもの 実際は送信しないよ </textarea> <br /> <input type="submit" name="submitBtn" value="送信!" /> <input type="hidden" name="key" value="<? print $key ?>" /> </form>
<?php /*----- 完了画面 -----*/ // セッション開始 session_start(); // 変数宣言 $msg = ""; // セッションに保持されているキーと、POSTで飛んできたキーが同じかどうか判別 if ( isset($_SESSION['key']) && isset($_POST['key']) && $_SESSION['key'] == $_POST['key']) { // 合致しているので、送信処理を記述 $msg = "送信しました"; } else { // 合致していないので、送信しない $msg = "失敗しました"; } // セッションに保持されているキーを破棄する ※重要※ unset($_SESSION['key']); ?> <? print $msg ?>ポイントとしては、
- 入力画面にてチェック用のキーを発行し、セッションに保存。
- お問い合わせの内容と一緒に、チェック用のキーをPOSTにて送信。
- 完了画面にて、送信処理の前にセッションに保持されているチェック用のキーと、POSTで飛んできた値が合致しているかチェック。
- 処理後、セッションに保持されているキーを破棄 ※重要※
こうすることで、一度送信した後は送信されなくなります。
簡単ですね!
注意としては、最後にキーを破棄しておかないとまったく意味が無いので、最後は必ず不要になったキーを破棄してください。
おまけ
実は、このプログラム手法によって、クロスサイトリクエストフォージェリ(CSRF)の対策にもなっています。攻撃ページから「end.php」に対してPOSTでデータを送信しても、セッション内に保持しているキーの値と、POSTで飛んでくるキーの値が合致しないので、攻撃が成立しません。
(※100%攻撃を防ぐ保障をするものではありません。複合的な要因により、攻撃出来る可能性は0ではないと思います。)
記事のタイトルには「お問い合わせフォーム」と書きましたが、様々なフォームで利用できるものですので、必要に応じて内容を変えつつ利用してください。
ちょっぴり幸せになれるかもしれませんよ。

- 脱出ゲームを作成しました
- Studio Yuksのサイト制作のお手伝いをさせていただきました
- よみがな.netを公開しました
- Slug or PostIDプラグインがバージョン1.0になりました。
- お問い合わせフォームへの連投を防ぐ方法+α
- phpMyAdminのsetup.phpに脆弱性があるみたいです
- 1つのデータベースに複数のWordPressをインストールする方法
- 仕事とプライベートで使っているマウスをご紹介
- WordPressでiFrameが消えないようにする記述が必要なくなったようです
- CSS3で横並びのメニューを簡単に作る方法
- HTML+CSS (8)
- JavaScript (12)
- PHP (21)
- PostgreSQL (4)
- WordPress (8)
- WordPressプラグイン (1)
- Movable Type (13)
- Photoshop (2)
- Illustrator (2)
- Firefox (5)
- ツール (2)
- 雑記 (23)
- 未分類 (3)
- Android (1)
コメントを残す