私はMicrosoftのASP.NETMVCチュートリアルに取り組んできましたが、このページに行き着きました
http://www.asp.net/learn/mvc/tutorial-32-cs.aspx
このページの下部に次のステートメントがあります。
一般に、Webアプリケーションの状態を変更するアクションを呼び出すときにHTTPGET操作を実行することは望ましくありません。削除を実行するときは、HTTP POST、さらにはHTTPDELETE操作を実行する必要があります。
これは本当ですか?誰かがこの声明の背後にある理論的根拠についてより詳細な説明を提供できますか?
ウィキペディア は次のように述べています:
一部のメソッド(たとえば、HEAD、GET、OPTIONS、TRACE)は安全であると定義されています。つまり、これらのメソッドは情報の取得のみを目的としており、サーバーの状態を変更するべきではありません。
対照的に、POST、PUT、DELETEなどのメソッドは、サーバーに副作用を引き起こす可能性のあるアクションを対象としています。
ジョンスキートの答えは標準的な答えです。しかし:あなたがリンクを持っているとしましょう:
href = "\myApp\DeleteImportantData.aspx?UserID=27"
そしてグーグルボットがやって来てあなたのページにインデックスを付けますか?それではどうなりますか?
GETには通常、副作用がありません。つまり、状態は変更されません。つまり、結果をキャッシュしたり、ブックマークを安全に作成したりできます。
実装者は、ソフトウェアがインターネットを介した対話においてユーザーを表すことを認識し、ユーザーが自分自身または他の人にとって予期しない重要性を持つ可能性のあるアクションを認識できるように注意する必要があります。
特に、GETメソッドとHEADメソッドは、取得以外のアクションを実行する意味を持たないようにする必要があります。これらのメソッドは「安全」と見なす必要があります。これにより、ユーザーエージェントが許可されます。 POST、PUT、DELETEなどの他のメソッドを特別な方法で表現し、安全でない可能性のあるアクションが要求されていることをユーザーに認識させます。
当然、GET要求を実行した結果としてサーバーが副作用を生成しないことを保証することはできません。実際、一部の動的リソースはその機能を考慮しています。ここでの重要な違いは、ユーザーが副作用を要求しなかったため、それらの責任を負わないことです。
べき等であることに関する純粋主義的な問題とは別に、実用的な側面があります。スパイダー/ボット/クローラーなどがハイパーリンクをたどります。 GETを実行するハイパーリンクとして「削除」アクションがある場合、Googleはすべてのデータを楽しく削除できます。 " The Spider of Doom "を参照してください。
投稿の場合、これはリスクではありません。
もう一つの例..
http://example.com/admin/articles/delete/2
ログインしていて適切な権限を持っている場合、これにより記事が削除されます。たとえば、サイトがコメントを受け入れ、ユーザーがそのリンクを画像として送信した場合。そのようです:
<img src="http://example.com/admin/articles/delete/2" alt="This will delete your article."/>
次に、管理者ユーザーがサイトのコメントを閲覧するようになると、ブラウザはそのURLにリクエストを送信して、その画像を取得しようとします。ただし、ブラウザがこれを実行している間にログインしているため、記事は削除されます。
ほとんどのブラウザは画像が見つからないと何も表示されないため、ソースコードを見ないと気付かないかもしれません。
それが理にかなっていることを願っています。
ここで私の答えを見てください 。それはこの質問にも同様に当てはまります。
- プリフェッチ:多くのWebブラウザはプリフェッチを使用します。つまり、リンクをクリックする前にページが読み込まれます。後でそのリンクをクリックすることを期待しています。
- ボット:情報を得るためにインターネットをスキャンしてインデックスを作成するボットがいくつかあります。 GETリクエストのみを発行します。このため、GETリクエストから何かを削除する必要はありません。
- キャッシング:GET HTTPリクエストは状態を変更することは想定されておらず、べき等である必要があります。べき等とは、リクエストを1回発行するか、複数回発行しても同じ結果が得られることを意味します。つまり副作用はありません。このため、GETHTTPリクエストはキャッシュと密接に関連しています。
- HTTP標準はそう言っています:HTTP標準は各HTTPメソッドが何のためにあるかを言います。いくつかのプログラムはHTTP標準を使用するように構築されており、それらはあなたが想定されている方法でそれを使用することを前提としています。したがって、従わないと、多数のランダムなプログラムから未定義の動作が発生します。
スパイダーとリクエストはべき等である必要があることに加えて、getリクエストにはセキュリティの問題もあります。誰かがあなたのユーザーに簡単に電子メールを送ることができます
<img src="http://yoursite/Delete/Me" />
テキストとブラウザは喜んで一緒に行き、リソースにアクセスしようとします。 POSTを使用することはそのようなことの治療法ではありません(javascriptでフォーム投稿を非常に簡単にまとめることができるため)が、それは良いスタートです。
このトピック(HTTPメソッドの使用法)については、次のブログ投稿を読むことをお勧めします: http://blog.codevader.com/2008/11/02/why-learning-http-does-matter/
これは実際には反対の問題です。データが変更されていないときにPOST)を使用しないのはなぜですか。
ここに記載されているすべての優れた理由とは別に、GETリクエストは受信サーバーによってログに記録される可能性があります(access.log
。リクエストでパスワードなどの機密データを送信すると、プレーンテキストとしてログに記録されます。
安全なDBストレージのためにハッシュ/ソルトされている場合でも、違反(またはIT担当者の肩越しに見ている人)によって明らかになる可能性があります。このようなデータは、POST本文に入れる必要があります。
インターネットバンキングアプリケーションがあり、転送ページにアクセスするとします。ログインしたユーザーは、$ 10を別のアカウントに転送することを選択します。
送信ボタンをクリックすると、(GETリクエストとして) https://my.bank.com/users/transfer?amount=10&destination=23lk3j2kj31lk2j3k2j にリダイレクトされます。
しかし、インターネット接続が遅いか、サーバーがビジーであるため、送信ボタンを押した後、新しいページの読み込みが遅くなっています。
ユーザーはイライラし、F5(ページの更新)を激しく押し始めます。何が起こると思いますか?複数の転送が発生し、ユーザーのアカウントが空になる可能性があります。
リクエストがPOST(またはGET以外)として行われた場合、最初のF5(ページの更新)ユーザーはブラウザに「本当にそれを実行しますか?副作用がある可能性があります[blabla bla] ... "
GETのもう1つの問題は、コマンドがブラウザのアドレスバーに移動することです。したがって、ページを更新すると、「最後のものを削除する」、「注文を送信する」などのコマンドを再度発行します。