POST後は必ずREDIRECTしますか?「はい」の場合、どのように管理しますか?

StackOverflow https://stackoverflow.com/questions/1083357

  •  23-08-2019
  •  | 
  •  

質問

たとえば、データベースに影響を与えるフォーム (レコードの追加/削除/更新) を送信しているとします。リクエストは次のようになります。

POST /application/action=update

さて、更新が完了したので、ユーザーをホームページに誘導したいとします。

Response.sendRedirect /application/action=home

これは素晴らしくうまくいきます。POST 後にユーザーにはリダイレクトが送信されるため、ユーザーが F5 キーを押してページを更新しようとしても問題ありません。ただし、これを実行した場合、これは機能しません。

requestDispatcher.forward(/application/action=home)

更新の完了後にさまざまな種類のエラー/成功メッセージを表示する必要があるシナリオがあることを考えると、POST の後に転送を実行している可能性が高くなります。このようなシナリオでは、更新アクションが 2 回発生するのをどのように回避すればよいでしょうか?

多くの安全なサイト (銀行) / 支払いゲートウェイが、「戻る / 更新ボタンを押さないでください」などのテキストを画面上に配置することでユーザーに通知する傾向があるのは、かなり面白いと思います。

これに対処するより良い方法はないでしょうか?ユーザーにこれらのボタンを押さないように要求する以外に?最後に確認したところ、「Vertical Response Cache」というものがありました。セッション内のリクエストの一意性を識別し、リクエストが重複している場合にキャッシュされたレスポンスの送信を試みるフィルター。この古典的な問題を解決するもっと簡単な方法はあるでしょうか?

これは、私が話した垂直応答キャッシュ ソリューションへのリンクです。 http://www.fingo.info/en/articles/_1.html. 。ただし、これが実際にどの程度うまく機能するかはわかりません。

役に立ちましたか?

解決

私が考えたことの 1 つは、POST 送信されるフォームに非表示のフォーム フィールドとして一意の ID (おそらくランダムな文字列) を埋め込むことです。ID 文字列は「トランザクション ID」としてデータベースに登録できます。ここで、データベースを更新するときは、まず、送信されたトランザクション ID を持つ既存のレコードがあるかどうかを確認し、存在する場合は重複しているものとみなし、データベースを変更しません。

もちろん、先ほども言いましたが、これは単なる考えです。実際にどのような手法が実践されているのかは分かりません。(重要度の低いサイトの多くは問題を無視し、ユーザーが賢明であることを期待しているのではないかと思います...もし私が見たことがあれば、これは負けの提案です ;-)

編集:コメントで指摘されているように、トランザクション ID をデータベースに保存すると多くのスペースが必要になる可能性がありますが、それが問題になる場合は、過去 5 分/1 時間/1 年間に処理されたすべてのトランザクション ID のメモリ内キャッシュを保持することができます。一日/何でも。決意の強いハッカーと対峙しない限り、これはうまくいくはずです...

他のヒント

はい、私はあなたのAPIリクエストを除いて、POST後にリダイレクトする必要があると考えています。だけでなく、これを実行することなく、ユーザーが戻るボタンを使用しますが、彼らは、[戻る]ボタンを使用しようとすると、ブラウザは、ユーザーに迷惑なダイアログを与える際に重複した投稿を心配する必要はない。

Response.sendRedirectは実際に動作しますが、tecnicallyこれを言えば、この目的のために間違ったHTTP応答コードを送信しています。 (彼らはPOSTに応じてそれを取得する場合、ほとんどのブラウザは、ちょうど303のような302を扱います、しかし)のsendRedirectが302を送信しますが、GETにPOSTを変換するために使用する正しいコードは303です。

一般的に、あなたはリダイレクトがその変更の影響を表示するものは何でもビューをユーザーに送信したいです。彼らはウィジェットを編集した場合、彼らはそのウィジェットのビューにリダイレクトする必要があります。彼らはウィジェットを削除すると、彼らはウィジェットは、それが存在していたときに登場しているだろうという見方(おそらくウィジェットリスト)にリダイレクトする必要があります。

時にはそれがさらに自宅アクションが発生したという事実を駆動するために、ステータスメッセージを持っていてうれしいです。これを行うための簡単な方法は、設定されたときに、アクション完了のメッセージが表示されます。あなたの意見に共通のパラメータを持つことです。例えばます:

/widget?id=12345&msg=Widget+modified.

ここで「MSG」パラメータは、「ウィジェットが改変された」のメッセージが含まれています。このアプローチの1つの欠点は、悪意のあるサイトがユーザーに混乱/誤解を招くようなメッセージを与えることが可能であることです。例えばます:

/account?msg=Foo+Corp.+hates+you.
あなたはこのことについて本当に心配している場合は、

あなたは、追加のパラメータとして、メッセージの期限切れの署名を含めることができます。署名が無効であるか、有効期限が切れている場合は、単にメッセージを表示しません。

リダイレクトGETにPOST後にユーザーにステータスメッセージを示すの問題を解決するための最善の解決策は、ユーザーセッションを使用することです。

をどのように

に表示されるメッセージのセットとして値をユーザセッションに属性を追加します。例えばのため。

userSession.put("success_messages", new HashSet<String>(){"Success", "Check your account balance"});
userSession.put("warning_messages", new HashSet<String>(){"Your account balance is low. Recharge immediately"});

そして、これらの特定の属性のユーザーセッションをスキャンし、メッセージを出力フィルタを持っています。ステータスメッセージは、一般的に一度だけ表示されるように、フィルタは、一度読んだ後の属性を削除する必要があります。

多くの安全なサイト (銀行) / 支払いゲートウェイが、「戻る / 更新ボタンを押さないでください」などのテキストを画面上に配置することでユーザーに通知する傾向があるのは、かなり面白いと思います。

「この重要なページのすべての戻る、更新イベントを無効にする」方が良いと考える人もいます。これが良いかどうかは分かりません。

しかし、あなたの解決策は「垂直応答キャッシュ「いいですね

少しわかりにくいですが:

  • ユーザーセッションでキー付きオブジェクトを作成します。
  • 値はリクエスト + 結果の Java Future です。
  • クライアント側のリダイレクトですぐに戻ります。
  • クライアント側のリダイレクトが処理されている間、ワーカー スレッドに応答の生成を実行させます。

したがって、クライアントブラウザがリダイレクトを完了して、新しいページの画像を取得するまでに...結果はユーザーを待っています。

別の方法は、データベースにどれくらいの時間がかかっているかをユーザーに痛感させることです。

セキュリティ アップデート (2011 年 1 月 24 日):

キーはクライアントへの応答の一部であるため、攻撃に対して脆弱です。

  1. ランダムなキーを生成する
  2. ユーザーのセッション ID をソルトとして使用して SHA-1 を作成します
  3. (,) を主キーとして、ランダム キーと SHA-1 の両方をデータベースに保存します。(RANDOMKEY に個別のインデックスは作成されません。
  4. RANDOMKEY と SHA-1 の両方を DB ルックアップとして使用します。
  5. セッション ID を保存しないでください (多くのエントリを同じユーザーに併置できることによるプライバシーの問題を回避します)
  6. 結果は 2 ~ 3 日後に期限切れになります。(毎日のバッチ ジョブでクリーンアップを実行できるようにし、半長期間続くユーザー セッションの問題の発生を回避します)

この方法では、ハッカーはセッション ID とランダム キーの両方を知っている必要があります。

このアプローチはやりすぎのように思えるかもしれませんが、リダイレクト強化メカニズムはパスワードのリセットなどの状況に使用できます。

あなたがJavaのサーバーサイド・スクリプトで作業しても、支柱2を使用している場合は、

あなたはトークンを使用して語るこのリンクを参照してください。

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

トークンが生成され、最初のページリクエストがトークンIDとスレッド名を持つスレッドを実行するStrutsアクションで、初めてのトークンと一緒に提出されたときに、レンダリングやロジックを実行するためのセッションに保管されなければならないものは何でもクライアントがまだ送信後、実行している場合、クライアントは503リダイレクト(。)(thread.getcurrentthreadを中断)クライアントは、もう一度同じ要求を提出したスレッドがまだ実行されているかどうかを確認するとき、ために要求しています。

支柱2codeのExecuteAndWaitInterceptorを見てください、トークンと組み合わせて、このの論理が速いクリックを手助けします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top