回答:
違いは、リダイレクトPOST
、リクエスト、PUT
およびDELETE
ユーザーエージェントの動作に対するサーバーの期待(RFC 2616
)に関するものです。
注:RFC 1945およびRFC 2068では、クライアントがリダイレクトされた要求のメソッドを変更できないように指定されています。ただし、既存のほとんどのユーザーエージェント実装では、302を303応答のように扱い、元のリクエストメソッドに関係なく、Locationフィールドの値に対してGETを実行します。ステータスコード303および307は、クライアントにどのような反応が期待されるかを明確にしたいサーバー用に追加されました。
また、30xリダイレクトコードに関するWikipediaの記事もご覧ください。
307が発生したのは、ユーザーエージェントが302応答を受信し、GET要求をLocation応答ヘッダーに送信するPOST要求を取得するために、事実上の動作として採用されたためです。
これは不正な動作です。303 のみがPOSTをGETに変える必要があります。元のPOSTリクエストが302を返した場合、ユーザーエージェントは、新しいURLをリクエストするときにPOSTメソッドを使用する必要があります(使用しないでください)。
307は、サーバーがユーザーエージェントに対して、Location応答ヘッダーをたどるときにメソッドの変更がクライアントによって行われるべきではないことを明確にすることを可能にするために導入されました。
302
正しく処理しません。Chrome 30、IE10。これは事実上正しくない実装になりました。多くのWebサイトが誤って302を発行するため、これを変更することはできません。実際、ASP.net MVC は、ブラウザーがそれを誤って処理するという事実に応じて、誤って302を発行します。
303
も導入さ307
れたため、HTTP 1.0ユーザーエージェントとの下位互換性を可能にするためです。もちろん、本当の問題は、今でもHTTP 1.0ユーザーエージェントを処理する必要があるかどうかです。
Response.RedirectSeeOther
)、およびクライアントが1.1でない場合(例えばGET /foo.html
、GET /foo.html HTTP/1.0
)その後、遺産を発行します302
。
動作中の良い例307 Internal Redirect
は、Google Chromeが、厳密なトランスポートセキュリティが必要であると認識しているドメインへのHTTP呼び出しを検出した場合です。
ブラウザは、元の呼び出しと同じ方法を使用してシームレスにリダイレクトします。
/register-form.html
に移動しましたsignup-form.html
。/register.php
に送信した場合、ロード(GET)し/success.html
ます。/register.php
これはにPOSTをやり直すように指示し/signup.php
ます。RFC 7231(2014年から)は非常に読みやすく、過度に冗長ではありません。正確な回答を知りたい場合は、お読みください。他のいくつかの回答は1999年のRFC 2616を使用していますが、変更はありません。
RFC 7238は308ステータスを指定しています。これは実験的なものと見なされていますが、2016年にはすでにすべての主要なブラウザでサポートされていました。
302の期待:リダイレクトはNEW_URLで同じリクエストメソッドPOSTを使用します
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL
302、303の実績:NEW_URLでPOSTからGETに変更リクエストメソッドをリダイレクト
CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
307の実績:リダイレクトはNEW_URLで同じリクエストメソッドPOSTを使用します
CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL
302はサーバーによって生成される一時的なリダイレクトで、307はブラウザーによって生成される内部リダイレクト応答です。内部リダイレクトとは、リダイレクトがブラウザーによって内部的に自動的に行われることを意味します。基本的に、ブラウザーはgetリクエストで入力されたURLをhttpからhttpsに変更してからリクエストを行うため、インターネットへの安全でない接続のリクエストは行われません。ブラウザがURLをhttpsに変更するかどうかは、ブラウザにプリインストールされているhstsプリロードリストに依存します。chrome:// net-internals /#hstsにある独自のブラウザーのhstsプリロードリストにドメインを入力することにより、httpsをサポートするサイトをリストに追加することもできます。所有者は、さらに1つのWebサイトドメインを追加できますhttps://hstspreload.org/のフォームに入力してリストをプリロードする特に自分でもできると言っても、すべてのユーザーのブラウザーにプリインストールされています。
例を挙げて説明し
ます。httpsのみをサポート
するhttp://www.pentesteracademy.comに getリクエストを行いましたが、サイトの所有者がドメインに登録していないため、ブラウザのhstsプリロードリストにそのドメインがありません。プリインストールされたhstsプリロードリストが付属しています。
安全でないバージョンのサイトに対するGETリクエストは、安全なバージョンにリダイレクトされます(上の画像の応答で、その場所の名前付きhttpヘッダーを参照してください)。
次に、chrome:// net-internals /#hstsのhstsドメインの追加フォームにドメインを追加して、自分のブラウザーのプリロードリストにサイトを追加します。これにより、Chromeブラウザーの個人用プリロードリストが変更されます。 STSオプションがあります。
hstsプリロードリストに追加した後、同じWebサイトの要求と応答を見てみましょう。
応答ヘッダーの内部リダイレクト307を確認できます。実際には、この応答はサーバーではなくブラウザーによって生成されます。
また、HSTSプリロードリストは、302リダイレクトがミット攻撃を受けやすいため、ユーザーが安全でないバージョンのサイトに到達するのを防ぐのに役立ちます。
リダイレクトについて理解を深めるのに少し役立ったと思います。
もともとあった 302
| Response | What browsers should do |
|------------------------|---------------------------|
| 302 Found | Redo request with new url |
アイデアは次のとおりです。
GET
ある場所でを行っていた場合はGET
、新しいURLにやり直しますPOST
ある場所でを行っていた場合はPOST
、新しいURLにやり直しますPUT
ある場所でを行っていた場合はPUT
、新しいURLにやり直しますDELETE
ある場所でを行っていた場合はDELETE
、新しいURLにやり直します残念ながら、すべてのブラウザがそれを間違っていました。取得する場合302
、彼らはいつもに切り替えてしまうGET
というと、要求を再試行するよりも、新しいURLに同じ動詞(例えば、POST
):
デファクトになりました間違いた。
すべてのブラウザで302
問題が発生しました。だから、303
および307
作成されました。
| レスポンス| ブラウザがすべきこと| ブラウザが実際に行うこと| | ------------------------ | ------------------------ --- | --------------------------- | | 302見つかりました| 新しいURLでリクエストをやり直す| 新しいURLで取得| | 303他を見る| 新しいURLで取得| 新しいURLで取得| | 307一時的なリダイレクト| 新しいURLでリクエストをやり直す| 新しいURLでリクエストをやり直す|
5種類のリダイレクト:
╔═══════════╤════════════════════════════════════════════════╗
║ │ Switch to GET? ║
║ Temporary │ No │ Yes ║
╠═══════════╪════════════════════════╪═══════════════════════╣
║ No │ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────┼────────────────────────┼───────────────────────╢
║ Yes │ 307 Temporary Redirect │ 303 See Other ║
║ │ 302 Found (intended) │ 302 Found (actual) ║
╚═══════════╧════════════════════════╧═══════════════════════╝
または:
| Response | Switch to get? | Temporary? |
|--------------------------|----------------|------------|
| 301 Moved Permanently | No | No |
| 302 Found (intended) | No | Yes |
| 302 Found (actual) | Yes | Yes |
| 303 See Other | Yes | Yes |
| 307 Temporary Redirect | No | Yes |
| 308 Permanent Redirect | No | No |
また、サーバー管理者にとって、307リダイレクトを使用する場合、ブラウザがユーザーにプロンプトを表示する場合があることに注意することが重要な場合があります。
たとえば、*、FirefoxとOperaはリダイレクトの許可をユーザーに要求しますが、Chrome、IE、Safariは透過的にリダイレクトを行います。
* Bulletproof SSLおよびTLSごと(192ページ)。
ユースケースによっては、攻撃者が307リダイレクトを悪用して、被害者の資格情報を入手する場合があります。
詳細については、OAuth 2.0の包括的な正式なセキュリティ分析のセクション3.1をご覧ください。。
上記の論文の著者は、次のことを提案しています。
修正。OAuth標準の現在の表現とは異なり、リダイレクトの正確な方法は実装の詳細ではありませんが、OAuthのセキュリティにとって不可欠です。HTTP標準(RFC 7231)では、HTTP POSTリクエストの本文を削除するために明確に定義されているのは303リダイレクトのみです。最も一般的に使用される302を含む他のすべてのHTTPリダイレクトステータスコードは、POSTリクエストとフォームデータを保持するオプションをブラウザに残します。実際には、ブラウザは通常、GETリクエストに書き直し、307リダイレクトを除いてフォームデータをドロップします。したがって、OAuth標準では、この問題を解決するために、上記の手順で303リダイレクトが必要です。