web-dev-qa-db-ja.com

ユーザーがページを再読み込みするときに複数のフォームが送信されないようにする方法

私は現在、サードパーティの統合を必要とするプロジェクトに取り組んでいますSOAP多くの基本的なCRUDタイプの操作を処理するAPI。

現在の実装では、これらのAPIリクエストデータの実行前にLaravelフレームワークのフォーム検証クラスを活用できますが、どのタイプのキューイングメカニズムも活用していないため、いくつかの懸念があります。

現在のソリューションスタックでは、NGINX Webサーバーに大きな負荷をかけて、ブロックしているユーザー要求ごとに追加のワーカーを生成します。明らかに、これはスケーラビリティの面で将来的にいくつかの問題につながる可能性があります。

ユーザーがフォームリクエストデータを送信した後、ページを頻繁に「更新」する可能性もあります。

可能な解決策として Post/Redirect/Get pattern を調査してきましたが、その概念を完全に理解していることはよくわかりません。

これは、1つのstackoverflow discussion からの引用です:

  1. クライアントはフォームのあるページを取得します。

  2. フォームはサーバーにPOSTします。

  3. サーバーはアクションを実行してから、別のページにリダイレクトします。

  4. クライアントはリダイレクトに従います。

上記のように、これらは長いAPI呼び出しであり、ステップ3の実行が完了するまでに10秒以上かかることがあります。ステップ2の後にユーザーがページを継続的に更新できないようにするにはどうすればよいですか?

5
user2308097

StackOverflowでもこの質問に回答しました-簡単に参照できるように私の回答を here としています...

PRGパターンだけではこれを防ぐことはできません。これは、Pアクションに時間がかかり(通常はそうです)、ユーザーが(クリックまたはブラウザの更新を介して)フォームを再度送信できるため、PRGパターンが「失敗」するためです。 。

悪意のあるユーザーは、複数のhttp投稿をすばやく連続して実行することにより、クライアント側のすべての対策を回避することもできます。

上記すべての解決策は、偽造防止トークンに対してサーバー側で重複した送信をチェックすることです。

フォームで非表示の偽造防止トークンを使用する場合(必要に応じて)、最初の送信時に偽造防止トークンをキャッシュし、必要に応じてトークンをキャッシュから削除するか、設定された時間後にキャッシュされたエントリを期限切れにすることができます。

その後、特定のフォームが送信されているかどうかをキャッシュに対して各リクエストで確認し、送信されている場合は拒否できます。

3
Daffy Punk

PRGパターンに従って、ステップ2の後に更新がある場合は、クライアント(ブラウザー)がリダイレクトURLを受信して​​使用するため、問題はないと思います。

この問題は、ステップ2が完了する前(リダイレクトURLを送信する前)にユーザーが更新すると発生します。

1
Ratha

一意のトークンを使用するサーバーソリューションは最も堅牢ですが、ユーザーフレンドリーではありません。ページが読み込まれるのを待ってリロード時にエラーを受け取るのは、優れたユーザーエクスペリエンスではありません。

クライアント側では、応答が受信される前に、データが処理され、送信/要求を拒否していることをUIのヒントとともにXHR要求を使用するように再設計できます。

0
iipavlov