web-dev-qa-db-ja.com

二重提出問題の解決

Web開発者が二重送信の問題をどのように回避するかを確認したいと思います。だから基本的に私の問題の理解は次のとおりです:

せっかちなユーザーがフォームを複数回送信すると、二重送信が発生し、問題が発生します。この問題は、フォームが送信されると送信ボタンを無効にするJavaScript(特にjQueryスクリプト)によって修正できます。これの弱点は、クライアントがJavaScriptを無効にしている場合です。

サーバー側の検出方法もあります。

だから私の質問は:

人々はどのようにして二重提出を克服しますか?二重提出によって引き起こされる問題の実際の例は何ですか?Webアプリケーションフレームワークには二重提出ツールが組み込まれていますか?

25
JHarley1

Javaサーバー側スクリプトを使用し、struts 2も使用している場合は、トークンの使用について説明しているこのリンクを参照してください。

http://www.xinotes.org/notes/note/369/

トークンが生成され、最初のページレンダリングのセッションで保持される必要があります。リクエストがトークンと共に初めて送信されたときに、Strutsアクションで、スレッドIDとしてスレッド名を使用してスレッドを実行し、クライアントが持つあらゆるロジックを実行します。が要求され、クライアントが同じ要求を再度送信するときに、スレッドがまだ実行されているかどうかを確認し(thread.getcurrentthread()。interrupted)、まだ実行されている場合はクライアントリダイレクト503を送信します。

Struts 2codeのExecuteAndWaitInterceptorを見てください。これのロジックとトークンを組み合わせると、高速クリックに役立ちます

8
Dead Programmer

実際の状況:賭けのWebサイトに賭けをする。ユーザーはダブルクリックして2つの賭けをします。良くない!これを防ぐには、JavaScriptチェックでは不十分でした。

解決:

  1. 作成 [〜#〜] uuid [〜#〜] / [〜#〜] guid [〜#〜] レンダリングするサーバー側スクリプト言語を使用してフォームに非表示の入力フォーム。

  2. フォームの送信時に、これをUniqueSubmissionsなどのデータベーステーブルにすぐに追加します。次に、処理を続行します。

  3. 同じUUID/GUIDを持つ後続のすべてのリクエストは、UniqueSubmissionsテーブルで見つかった場合、拒否されます。

これでうまくいきました。それがあなたの質問への回答に役立つことを願っています!

18
Ciaran Archer

redirect-after-post を使用するか、時には PRG(post/redirect/get) と呼ばれる

つまり、ユーザーがフォームを投稿すると、(投稿データを使用した後)応答(成功)ページへのクライアント側リダイレクトが実行されます。

7
Joel

実際の例では、この回答が2回投稿されます;-)。クライアント側の任意の側面(JavaScriptまたはCookie)に依存したくない場合は、送信元IPや使用されているブラウザーなどの情報を追加して、送信されたデータのMD5ハッシュを計算し、投稿を拒否できます。同じハッシュを持っている。

5
Yack

web2py フレームワークには、二重フォームの送信に対する 組み込みの保護 があります。ワンタイムトークンはセッションとフォームの非表示フィールドに格納され、送信時に一致する必要があります。一致しない場合、送信は拒否されます。この方法も CSRFから保護 (クロスサイトリクエストフォージェリ)。

3
Anthony

フォームにサーバーのdbmsにデータを保存するためのインターフェースを提供する意図がある場合は、送信されたデータに必須の特別なリビジョンフィールドを使用できます。送信されたリビジョンがデータベース内のデータの最新バージョンのリビジョンと一致するかどうか(または挿入される新しいデータの一部かどうか)をチェックすると、複数の送信が行われた場合の処理​​を適切に制御できます順番通りに。

2

Struts Webアプリケーションフレームワークを使用して、この問題を次のように処理できます。

Strutsには、token, saveToken(), isTokenValid() and resetToken()に使用する3つのメソッドがあります。

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);
}
_

参照

1
Premraj