Por que você deve excluir usando um HTTP POST ou DELETE, ao invés de GET?
-
16-09-2019 - |
Pergunta
Tenho vindo a trabalhar através de tutoriais ASP.NET MVC da Microsoft, terminando nesta página
http://www.asp.net/learn/mvc/ tutorial-32-cs.aspx
A seguinte declaração é feita em direção ao fim da página:
Em geral, você não quer executar uma operação HTTP GET ao chamar uma ação que modifica o estado de sua aplicação web. Ao realizar uma exclusão, que deseja executar um HTTP POST, ou melhor ainda, uma operação DELETE HTTP.
Isso é verdade? Alguém pode oferecer uma explicação mais detalhada para a lógica por trás dessa afirmação?
Editar
Wikipedia afirma o seguinte:
Alguns métodos (por exemplo, HEAD, GET, opções e TRACE) são definidos como seguro, o que significa que eles são destinados apenas para a recuperação de informações e não deve alterar o estado do servidor.
Por outro lado, métodos tais como o POST, PUT e excluir se destinam para as acções que podem causar efeitos colaterais tanto no servidor
Solução
A resposta de Jon Skeet é a resposta canônica. Mas: Suponha que você tenha um link:
href = "\myApp\DeleteImportantData.aspx?UserID=27"
eo google-bot vem e índices sua página? O que acontece então?
Outras dicas
GET é convencionalmente livre de efeitos colaterais - em outras palavras, isso não muda o estado. Isso significa que os resultados podem ser armazenados em cache, bookmarks podem ser feitas com segurança etc.
A partir o HTTP 1.1 RFC 2616
Os implementadores devem estar cientes de que o software representa o usuário em sua interações através da Internet, e deve ter cuidado para permitir que o usuário estar ciente de quaisquer acções que possam assumir que pode ter um inesperado significado para si ou para outrem.
Em particular, a convenção foi estabelecido que o GET e HEAD métodos não deve ter o importância de tomar uma ação outra de recuperação. Estes métodos deveriam ser considerado "seguro". Isso permite que o usuário agentes para representar outros métodos, tais como o POST, PUT e excluir, numa modo especial, para que o usuário é feita ciente do fato de que um possivelmente ação insegura está sendo solicitado.
Naturalmente, não é possível garantir que o servidor não gerar efeitos secundários como resultado de executar uma solicitação GET; de fato, alguns recursos dinâmicos considerar que uma característica. A distinção importante aqui é que o usuário não fez pedido os efeitos colaterais, assim, portanto, não pode ser responsabilizados por eles.
Além das questões puristas em torno de ser idempotent, há um lado prático: aranhas / bots / crawlers etc seguirá hyperlinks. Se você tem sua ação "excluir" como um hiperlink que faz um GET, o Google pode alegremente apagar todos os seus dados. Consulte " The Spider of Doom ".
Com mensagens, este não é um risco.
Outro exemplo ..
http://example.com/admin/articles/delete/2
Isto irá excluir o artigo, se você está logado e tem os privilégios corretos. Se o seu site aceita comentários, por exemplo, e um usuário envia que apontam como uma imagem; como assim:
<img src="http://example.com/admin/articles/delete/2" alt="This will delete your article."/>
Então, quando você se como o usuário admin vir para navegar através dos comentários em seu site o navegador tentará buscar essa imagem enviando fora um pedido nesse URL. Mas porque você está logado, enquanto o navegador está fazendo isto o artigo vai ficar excluído.
Você pode nem notar, sem olhar para o código-fonte como a maioria dos navegadores não vai mostrar nada se não puder encontrar uma imagem.
A esperança que faz sentido.
Por favor, veja a minha resposta aqui . Aplica-se igualmente a esta pergunta.
- Prefetch: Um monte de navegadores Web usará pré-busca. Que significa que ele vai carregar uma página antes de Clique no link. prevendo que você vai clicar no link mais tarde.
- Bots: Existem vários bots que digitalizar e indexar a internet para em formação. Eles só emitirá GET solicitações de. Você não quer apagar algo de um pedido GET para este razão.
- Cache: HTTP GET solicitações não são suposto estado de mudança e eles devem ser idempotent. meios idempotentes que emitir um pedido uma vez, ou emite várias vezes dá o mesmo resultado. Ou seja, Não tem efeitos colaterais. Para esta razão HTTP GET solicitações são firmemente amarrada ao armazenamento em cache.
- HTTP padrão diz assim : O padrão HTTP diz o que cada método HTTP é para. Vários programas são construídos para usar o padrão HTTP, e eles assumem que você vai usá-lo da maneira que você é suposto. Assim você terá indefinido comportamento de uma série de programas aleatórias se você não seguir.
Além de aranhas e os pedidos têm que ser idempotent há também um problema de segurança com solicitações GET. Alguém pode facilmente enviar seus usuários um e-mail com
<img src="http://yoursite/Delete/Me" />
no texto eo navegador irá alegremente ir junto e tentar acessar o recurso. Usando POST não é uma cura para essas coisas (como você pode montar um post de formulário em javascript muito facilmente), mas é um bom começo.
Sobre este tópico (HTTP uso de métodos), eu recomendo a leitura deste post: http://blog.codevader.com/2008/11/02/why-learning-http-does-matter/
Este é realmente o problema oposto: por que não usar POST quando nenhum dado é alterado.
Vamos dizer que temos uma aplicação de internet banking e visite a página de transferência. O logado escolhe usuário para transferir US $ 10 para outra conta.
Ao clicar no botão redirecionamentos (como um pedido GET) para https apresentar: //my.bank.com/users/transfer?amount=10&destination=23lk3j2kj31lk2j3k2j
Mas a conexão à internet é lento e / ou (s) servidor é (são) tão ocupado depois de bater no botão enviar a nova página é de carregamento lento.
O usuário fica frustrado e começa a bater F5 (atualização da página) furiosamente. Adivinhar o que vai acontecer? Mais do que uma transferência ocorrerá possivelmente esvaziar a conta do usuário.
Agora, se o pedido for feito como POST (ou qualquer outra coisa do que GET) o primeiro F5 (atualização da página) o usuário fará com que o navegador irá delicadamente perguntar "você tem certeza que quer fazer isso? Ele pode ter efeitos secundários [ bla bla bla] ... "
Além de todas as excelentes razões mencionadas aqui, solicitações GET pode ser registrado pelo servidor do destinatário, tal como no access.log
. Se você enviar através de dados confidenciais, como senhas no pedido, eles são registrados como texto simples.
Mesmo se eles estão em hash / sal para armazenamento DB seguro, uma violação (ou alguém olhando por cima do ombro do rapaz TI) poderia revelá-los. Tais dados devem ir no corpo POST.
Outro problema com GET é que o comando vai para a barra de endereços do navegador. Então, se você atualizar a página, você emitir o comando novamente, seja ela "última coisa de exclusão", "enviar o pedido" ou similar.