3

多くのフォームを使用して GWT アプリケーションを構築しています。ディスパッチ モジュールで gwt-platform を使用しています。

私の考えている次のステップは、サーバー側での二重送信を防ぐことです。問題は、それを正確に行う方法がわからないことです...

私は次のようなことを考えました:

  1. アプリケーションがロードされると、サーバーは生成されたトークンをクライアントに提供します
  2. サーバーは HTTPSession 内にトークンを保存します
  3. クライアントがフォームを送信すると、(1.) からのトークンがフォームとともに送信されます。
  4. サーバーは、送信されたトークン == HTTPSession 内のトークンであるかどうかを確認します
  5. クライアントへの応答で、新しいトークンを送信します

トークンを HTTPSession 内に保存しても安全ですか? または、サーバー上で SESSION_ID から生成されたトークンにマップする HashMap を作成する必要がありますか?

それとも、GWT や gwt-platform などで既に実装されているのでしょうか?

ありがとう

4

1 に答える 1

5

最初に自問しなければならない質問は、次のとおりです。回避したい問題のシナリオはどのようなものですか?

  1. ユーザーが誤って (またはイライラして ...) ボタンを 2 回クリックした。
  2. 1 回しか利用できないリソース (飛行機の特定の座席の予約など) が 2 回消費されること。

「どちらも避けたい」とだけ言わないでください。その場合でも、2 つの問題を別々に処理する必要があります。

問題1

これは、クライアント側でより適切に解決されます (たとえば、クリックされたボタンを無効にするなど)。

サーバー側でも解決できますが(シーケンス番号やトークン、またはコンテンツのハッシュコードをチェックすることで...)、ポイントがわかりません。ユーザーが本当に 2 回送信したい場合 (たとえば、ボタンが無効にならないように JavaScript を操作するなど) は、許可してください。問題 1 はセキュリティに関するものではありません。

問題 2

これは (非常に特殊な状況を除いて) サーバー側で解決する必要があります。主にセキュリティについてです。しかし、考えてみると、この問題は二重送信防止では解決できません! なぜだめですか?

例を見てみましょう: 飛行機の座席は 1 回だけ予約する必要があります。これは、複数の方法で違反される可能性があります。

  • 二重提出によって。
  • 同じユーザーが同時に別のブラウザ ウィンドウから送信するなど。
  • 複数のユーザーが同時に予約しようとした場合。

この問題を解決するクリーンな方法は、座席を予約してアトミックに座席の空室状況を確認することです。違反が二重送信によって引き起こされた場合、それは実際には問題ではありません (偶発的な二重送信は問題 1 でカバーされます)。

...そして問題3

自動再送信メカニズムを実装している場合は、第 3 の種類の問題も発生する可能性があります。

ユーザーが自分のショッピング カートに商品を追加したいとします。クライアントが送信し、タイムアウト前にサーバーからの応答を受信しません。そのため、自動的に再送信されます。ただし、サーバーは両方のメッセージを受信し、両方を処理しようとします。そのため、アイテムがショッピング カートに 2 回追加されます。

私の意見では、これを回避するための最善の解決策は、通常、「カートに 1 つのアイテムを追加する」などのアクションを使用するのではなく、「アイテムの目標数を 1 に設定する」ことです。繰り返しますが、シーケンス番号などを操作することもできます。

于 2012-05-21T07:48:18.220 に答える