二重提出の問題の解決
-
11-10-2019 - |
質問
Web開発者が二重の提出の問題を回避する方法を見たいです。したがって、基本的に問題についての私の理解は次のとおりです。
焦りのユーザーがフォームを複数回提出して問題を引き起こすと、二重の提出が発生します。この問題は、フォームが提出されたら送信ボタンを無効にするJavaScript(特にjQueryスクリプト)によって修正できます。これの弱点は、クライアントがJavaScriptを無効にしている場合です。
サーバー側の検出方法もあります。
だから私の質問は次のとおりです。
人々はどのように二重の提出を克服しますか?二重提出によって引き起こされる問題の実際の例は何ですか? Webアプリケーションフレームワークには、二重の提出ツールが組み込まれていますか?
解決
Java Server Side Scriptingを使用していて、Struts 2を使用している場合は、Tokenの使用について説明するこのリンクを参照してください。
http://www.xinotes.org/notes/note/369/
トークンを生成し、最初のページレンダリングのセッションに保持する必要があります。リクエストが初めてトークンとともに送信されたときに、ストラットアクションでは、クライアントが持っているものをすべてトークンIDとしてスレッド名でスレッド名を実行し、スレッド名を実行します要求された場合、クライアントが同じリクエストを再度送信する場合、スレッドがまだ実行されているかどうかを確認します(thread.getCurrentThread()。中断されます)。
struts 2codeのexecueandwaitinterceptorをご覧ください。これとトークンの組み合わせのロジックは、速いクリックを支援します
他のヒント
実生活の状況:賭けウェブサイトに賭けをする。ユーザーはダブルクリックして、2つのベットを配置します。良くない! JavaScriptのチェックは、これを防ぐのに十分ではありませんでした。
解決:
フォームの提出について、すぐにこれを呼び出すデータベーステーブルに追加します
UniqueSubmissions
(例えば)。次に、処理を続行します。同じUUID/GUIDを使用した後続のリクエストはすべて、
UniqueSubmissions
テーブル。
これは私たちのために働きました。それがあなたの質問に答えるのに役立つことを願っています!
使用 リダイレクトアフターポスト または時々呼ばれます prg(post/redirect/get)
要するに、ユーザーがフォームを投稿すると、クライアント側のリダイレクト(投稿データを消費した後)を応答(成功)ページに実行します。
実際の例は、この回答が2回投稿されたものです;-)。クライアント側のいずれかの側面(JavaScript、またはCookie)に依存したくない場合は、おそらくソースIPや使用したブラウザなどの情報を追加して投稿して投稿を拒否して、送信されたデータのMD5ハッシュを計算できます。同じハッシュを持っています。
web2py フレームワークにはあります 組み込み保護 ダブルフォームの提出に対して。セッションに1回限りのトークンを保存し、フォームの隠されたフィールドに保存します。提出時に一致するか、提出が拒否されます。この方法も CSRFから保護します (クロスサイトリクエスト偽造)。
フォームに、サーバーDBMSにデータを保存するためのインターフェイスを提供する意図がある場合、送信データに必須の特別な改訂フィールドを使用できます。提出されたリビジョンがデータベース内のデータの最新バージョンのそれと一致するかどうか(または挿入する新しいデータのものと一致するかどうかを確認すると、いくつかの提出物が作成された場合の対処方法を適切に制御できます。順番通りに。
Struts Webアプリケーションフレームワークを使用して、次のようにこの問題を処理できます。
Strutsには、3つの方法が使用されています token, saveToken(), isTokenValid() and resetToken()
.
saveToken()
- トークンキーを生成し、リクエスト/セッション属性に保存します。
isTokenValid()
- リクエスト/セッションで1ストアに対して送信されたトークンキーを検証します。
resetToken()
- トークンキーをリセットします。
使い方:
1)フォームを読み込むと、呼び出します saveToken()
アクションクラスで、トークンキーを作成および保存します。 Strutsは、生成されたキーをリクエスト/セッションに保存します。トークンが正常に作成された場合、ブラウザのソースを表示すると、次のようなものが表示されます。トークンキーは隠されたフィールドとして保存されます。
<form action="myaction.do" method="post">
<input type="hidden"
name="<%= Constants.TOKEN_KEY %>"
value="<%= session.getAttribute(Action.TRANSACTION_TOKEN_KEY) %>" >
2)フォームが送信されたら、呼び出します isTokenValid()
アクションクラスでは、リクエスト/セッションに基づいて以前に保存されたトークンキーを使用して、提出されたトークンキー(非表示フィールド)を検証します。一致すると、trueが返されます。
public final ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
saveToken(request);
if (!tokenIsValid(request)) {
//forward to error page saying "your transaction is already being processed"
} else {
//process action
//forward to jsp
}
// Reset token after transaction success.
resetToken(request);
}