phpメールの多重送信への対応
phpのmb_sendmail関数を使った問い合わせフォームでの怖い話。
問い合わせフォームから、何度も同じメールが、日時を変えて送られてくるらしい。初回の送信から、日を変え、時間を変え、何度も何度も送られてきて(15件と聞いた)困っているという。
はじめはスパムやロボットを疑ったが、どうも内容は至って普通のお問い合わせで、ユーザーも悪意のある感じではない。10年近く前に、他社さんで作られたサイトらしく、当然仕様書も無い。
当該のフォームはphpで書かれていて、mb_sendmailを使ったごく普通のメールフォームだった。
mb_sendmailは、ホームページから簡単にメールを送れる便利な関数だけど、ちゃんと使おうと思ったら、スパム対策とかセッション管理がとても大切。
多重送信をブロックする仕組みにしていないと、ページのリロードや、送信ボタン連打で、同じメールが何度も送られてしまう。
実際に、上のメールフォームでは、送信完了画面でリロードを行うと、リロードの数だけメールが送信されてしまっていた。
対応方法
処理の終わりにリダイレクトを入れる
/* 指定のページへリダイレクト */
header("location: https://lofir.net");
/* 3秒後に指定のページへリダイレクト */
header(“refresh:3;https://lofir.net”);
php の仕様で header 関数は html の出力より前に記述する必要があるため、条件分岐等でhtml内に組み込む必要がある場合は、phpではなくjavascriptによるリダイレクトの方法もある。
/* 3秒後に指定のページへリダイレクト */
<script>
setTimeout(function(){
window.location.href = 'https://lofir.net';
}, 3*1000);
</script>
セッションを破棄する
セッションを利用しているタイプのフォームの場合は、セッションをクリアしてしまえば、メールが送信されることはない。
/* セッション変数の消去 */
$_SESSION = array();
/* セッションクッキーの破棄 */
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
/* セッションIDの破棄 */
session_destroy();
セッションって?
ここでいう、セションとは、ユーザーがWebサイトにアクセスしてから離脱(ブラウザを閉じるか、一定時間の経過)するまでの一連の通信のこと。
セッションはアクセス解析にも指標としてよく使われる。
セッションは、以下の2つの要素から構成されている。
要素 | 内容 | データの保存先 |
---|---|---|
セッションID | セッションを一意に識別するID | ブラウザ(主にCookie) |
セッションデータ | ユーザーが入力したフォームデータや、ユーザーが閲覧したページなどのデータ | サーバー |
セッションを使うと、以下のようなことができる。
- ユーザーが入力したフォームデータを保存する
- ユーザーが閲覧したページを保存する
- ユーザーのログイン状態を保存する
スパム対策はreCAPTCHAに任せる。