Por que uma solicitação GET não deve alterar dados no servidor?

95

Em toda a Internet, vejo os seguintes conselhos:

A GET should never change data on the server- use a POST request for that

Qual é a base para essa ideia?

Se eu fizer um serviço php que insere dados no banco de dados e passar os parâmetros na string de consulta GET, por que isso está errado? (Eu estou usando instruções preparadas, para cuidar de Injeção de SQL). Uma solicitação POST é, de alguma forma, mais segura?

Ou há alguma razão histórica para isso? Se sim, quão válido é este conselho hoje?

    
por Devdatta Tengshe 01.03.2013 / 13:15
fonte

6 respostas

174

Isto não é um conselho.

Um GET é definido dessa forma no protocolo HTTP . É suposto ser idempotente e safe .

Quanto ao porquê - um GET pode ser armazenado em cache e em um navegador, atualizado. Mais e mais e mais.

Isso significa que se você fizer o mesmo GET novamente, você irá inserir em seu banco de dados novamente .

Considere o que isso significa se o GET se tornar um link e for rastreado por um mecanismo de pesquisa. Você terá seu banco de dados cheio de dados duplicados.

Também sugiro a leitura de URIs, capacidade de endereçamento e o uso de HTTP GET e POST .

Existe também um problema com a pré-busca de links em alguns navegadores - eles farão uma chamada para buscar previamente os links, mesmo que não seja indicado pelo autor da página.

Se, digamos, o seu logout estiver por trás de um "GET", vinculado de todas as páginas do seu site, as pessoas poderão ser desconectadas apenas devido a esse comportamento.

    
por 01.03.2013 / 13:18
fonte
22

Cada verbo HTTP tem sua própria responsabilidade. Por exemplo, GET , conforme definido por RFC

means retrieve whatever information (in the form of an entity) is identified by the Request-URI.

POST , por outro lado, significa inserir ou mais formalmente

The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line

Razões para continuar assim:

  • É muito simples e funciona na escala global da Internet desde 1991
  • Siga o princípio da responsabilidade única
  • Outras partes usam GET para atuar como meio de recuperação de informações e mineração de dados
  • GET é considerado uma operação segura que nunca modifica o estado do recurso
  • Considerações de segurança, GET é efetivamente uma leitura , enquanto POST é efetivamente uma gravação
  • GET é armazenado em cache por navegadores, nós na rede, provedores de serviços de Internet
  • A menos que o conteúdo mude, GET para o mesmo URL deve retornar os mesmos resultados para todos os usuários, senão você não terá qualquer confiança no resultado retornado

Para completar e apenas para garantir o uso correto (fonte) :

  • Os parâmetros GET são passados como parte da URL, que é de tamanho pequeno e limitado de 256 caracteres por padrão, com alguns servidores suportando 4000 caracteres. Se você quiser inserir um registro longo, não há uma maneira legítima de passar esses dados em
  • Ao usar conexão segura, ̶ como o TLS, ̶ URL é não conseguir criptografado, ̶, logo, todos os parâmetros do ̶ ̶G̶E̶T̶ ̶ são transferidos Texto simples. O URL é realmente criptografado com TLS, portanto, o TLS é bom.
  • Inserir dados binários ou caracteres não-ASCII usando GET é impraticável
  • GET é executado novamente se um usuário pressionar um botão Voltar em um navegador
  • Alguns rastreadores mais antigos podem não indexar URLs com um sinal ? dentro de
por 01.03.2013 / 15:30
fonte
9

EDIT: Antes, eu disse que o POST ajuda a protegê-lo contra o CSRF, mas isso está errado. Eu não pensei nisso corretamente. Você deve exigir um token oculto exclusivo do escopo da sessão em todas as suas solicitações para alterar os dados para proteção contra o CSRF.

Nos primeiros dias da internet, havia aceleradores de navegador. Esses programas começariam clicando em links em uma página para armazenar o conteúdo em cache. O Google Web Accelerator era um desses programas. Isso pode causar estragos em um aplicativo que faz alterações quando um link é clicado. Eu faria a suposição de que ainda existem pessoas usando o software acelerador.

Servidores proxy e navegadores armazenam em cache solicitações GET, de modo que quando o usuário acessa a página novamente, ele não pode enviar a solicitação ao seu aplicativo para que o usuário ache que realizou uma ação, mas na verdade não o fez.

    
por 01.03.2013 / 19:28
fonte
8

If I make a php service which inserts data in the database, and pass it parameters in the GET query string, why is that wrong?

A resposta mais simples é "porque não é isso que GET significa".

Usar GET para passar dados para uma atualização é como escrever uma carta de amor e enviá-la em um envelope marcado como "OFERTA ESPECIAL - AGAR AGORA!" Em ambos os casos, você não deve se surpreender se o destinatário e / ou intermediários manejarem mal sua mensagem.

    
por 02.03.2013 / 16:40
fonte
5

Para as operações de CRUD em um aplicativo centrado no banco de dados, use o seguinte esquema:

Use HTTP GET para operações de leitura (SQL SELECT)

Use HTTP PUT para operações de atualização (SQL UPDATE)

Use HTTP POST para criar operações (SQL INSERT)

Use HTTP DELETE para operações de exclusão (SQL DELETE)

    
por 05.03.2013 / 22:43
fonte
0

A GET should never change data on the server- use a POST request for that

Esse conselho e todas as respostas aqui estão erradas. Obviamente estou sendo excessivamente dramático, as outras respostas são excelentes, mas acredito que o conselho exato deve ser dado como:

A GET should rarely change data on the server- use a POST request for that

Dizer "nunca" é muito radical e, embora as outras respostas aqui expliquem com precisão por que você deveria "raramente" fazê-lo, há alguns cenários em que é perfeitamente razoável alterar os dados com um GET. Um exemplo é um link de verificação de e-mail de uso único. Normalmente, esses links contêm um GUID que, quando acessado, precisará alterar os dados. Se implementadas corretamente, solicitações GET idênticas subsequentes serão ignoradas.

Este é obviamente um caso extremo, mas certamente digno de nota.

    
por 28.12.2015 / 17:45
fonte