二重サブミット対策とか
バズっていたので個人的感想。
コメントつけようかと思っていたが、第三者的には有効な情報ではない気もしたので、ここで。
記事の内容
二重サブミットが発生する状況
- サブミットボタンをダブルクリックする
- 戻るボタンで戻って、再度保存ボタンを押す
- 完了ページでブラウザリロードする
- CSRF攻撃による不正な更新リクエスト
対策
- トークンによるチェック
- JavaScriptでのサブミットボタンのDisable化
- PRGパターン
でもって、
ここから個人的な感想。
そもそも二重サブミット対策をするか?
単純な問い合わせフォームやアンケートフォーム等については、PRGパターンのみ採用し(完了画面リロードによる登録防止)、他はしないかもしれない。
同一人物の複数登録チェックが必要な場合、どのみちそれはデータクリーニング時に必須な工程となるから。
そう考えると、「トークンによるチェック」等は認証前提の会員系サイトへの対応で限定される気がする。
「トークンによるチェック」
CSRF対策としては、最近この手法を使うことが多い(自分の記事)。
ただ、この場合、1ページ1トークンの為、「戻るボタン」の処理が行えない。
(CSRFチェックのエラーとなる)
「戻るボタン」を有効にするか?
入力ー確認ー完了でトークンを同じにすることで、戻るボタンで画面を戻ってリクエストを再送信しても、完了画面以外はエラーにならず(!)、ユーザビリティが確保されます。
例えば、確認画面に「入力画面へ戻る」ボタンをつけなくても、ブラウザの戻るボタンで遷移することができ、トークンエラーにもなりません!
ユーザビリティが落ちるのは承知だが、「確認ページから入力ページへの遷移の為の戻るボタン動作は保証しません」と言い切ることが多い。
- 動作ブラウザや状況によって、キャッシュの扱い状況がバラバラ過ぎて、サーバサイドで管理するのが難しい。
- 「入力エラー発生時ページ」も合わせて考える必要がある。
- JavaScriptによる動的な画面更新や入力値補完が行われていた場合、それが全て残っているとは限らない。
もし対応する場合、最近であれば、pushState機構を用いて遷移を制御するのが正道なのかな、と思う。
「入力」=>「確認」=>「完了」について
そもそも「確認ページが必須」というのが割と日本的文化の為、多くのフレームワーク自体はその機能を持っていないのでは?とは思っている。
(項目数の関係で)入力画面が複数にわたる場合、文化に関わらず、確認画面は必要になると思うのだが、それはそれで一般化しにくい仕様なので、標準機能としては備えてないのだろう。
「JavaScriptでのサブミットボタンのDisable化」
古いWEBアプリケーションの場合、Disable化対応が原因で誤動作を起こしているものがたまにあるので、個人的にイメージがあまり良くないが、
ただ、回線が遅く遷移前にブラウザの停止ボタンを押した場合は、ボタンを二度と押せなくなってしまうため、↑の方式に一定時間でボタンをenabledにするようにした方が親切です。
ダブルクリック対策の参考として良いかも。
「PRGパターン」
リダイレクトさせる方法は知っていたが、パターン名がついているのは知らなかった。