Perché una richiesta GET non dovrebbe modificare i dati sul server?

95

Su Internet, vedo il seguente consiglio:

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

Qual è la base di questa idea?

Se creo un servizio php che inserisce dati nel database e lo inoltro ai parametri nella stringa di query GET, perché è sbagliato? (Sto usando le dichiarazioni preparate per occuparmi di SQL Injection). Una richiesta POST è in qualche modo più sicura?

O c'è qualche motivo storico per questo? Se sì, quanto è valido oggi questo consiglio?

    
posta Devdatta Tengshe 01.03.2013 - 13:15
fonte

6 risposte

173

Questo non è un consiglio.

Un GET è definito in questo modo nel protocollo HTTP . Dovrebbe essere idempotente e sicura .

Per quanto riguarda il motivo: un GET può essere memorizzato nella cache e in un browser, aggiornato. Ancora e ancora.

Ciò significa che se ridicherai lo stesso GET , inserirai nuovamente nel tuo database .

Considera cosa può significare se GET diventa un link e viene sottoposto a scansione da un motore di ricerca. Avrai il tuo database pieno di dati duplicati.

Suggerisco anche di leggere gli URI , l'indirizzabilità e l'uso di HTTP GET e POST .

C'è anche un problema con collegamento prefetching in alcuni browser - effettueranno una chiamata ai collegamenti di precaricamento, anche se non indicato così dall'autore della pagina.

Se, per esempio, il tuo log out è dietro un "GET", collegato da ogni pagina del tuo sito, le persone possono essere disconnessi solo a causa di questo comportamento.

    
risposta data 01.03.2013 - 13:18
fonte
22

Ogni verbo HTTP ha la propria responsabilità. Ad esempio GET , come definito da RFC

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

POST , d'altra parte, significa inserire o più 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

Motivi per tenerlo in questo modo:

  • È molto semplice e funziona sulla scala globale di Internet dal 1991
  • Attenersi al principio di responsabilità singola
  • Le altre parti utilizzano GET per fungere da mezzo di recupero delle informazioni e di data mining
  • GET si presume che sia un'operazione sicura che non modifica mai lo stato della risorsa
  • Considerazioni sulla sicurezza, GET è effettivamente una lettura , mentre POST è effettivamente una scrittura
  • GET viene memorizzato nella cache da browser, nodi nella rete, provider di servizi Internet
  • A meno che il contenuto non cambi, GET allo stesso URL deve restituire gli stessi risultati a tutti gli utenti oppure non avrai alcuna fiducia in ciò che mai nel risultato restituito

Per completezza e solo per far rispettare l'uso corretto (source) :

  • I parametri GET vengono passati come parte dell'URL, che è di lunghezza piccola e limitata di 256 caratteri per impostazione predefinita, con alcuni server che supportano più di 4000 caratteri. Se desideri inserire un record lungo, non esiste un modo legittimo per trasferire questi dati in
  • Quando si utilizza connessione sicura, ̶ come TLS, ̶ URL è non ottenere criptato, ̶ Quindi tutti i parametri del ̶ ̶G̶E̶T̶ ̶ sono trasferiti Testo normale. L'URL è interamente crittografato con TLS, quindi TLS va bene.
  • L'inserimento di dati binari o caratteri non ASCII utilizzando GET non è pratico
  • GET viene rieseguito se un utente preme un pulsante Indietro in un browser
  • Alcuni crawler più vecchi potrebbero non indicizzare gli URL con un segno ? all'interno
risposta data 01.03.2013 - 15:30
fonte
9

EDIT: Prima, ho detto che il POST ti aiuta a proteggerti contro CSRF ma questo è sbagliato. Non l'ho pensato correttamente. È necessario richiedere un token nascosto univoco per la sessione in tutte le richieste per modificare i dati per la protezione da CSRF.

Nei primi giorni di Internet c'erano gli acceleratori del browser. Questi programmi inizieranno a fare clic sui collegamenti su una pagina per memorizzare il contenuto nella cache. Google Web Accelerator era uno di questi programmi. Ciò potrebbe provocare il caos su un'applicazione che apporta modifiche quando si fa clic su un collegamento. Direi che ci sono ancora persone che usano il software di accelerazione.

I server proxy e i browser memorizzeranno nella cache le richieste GET, quindi quando l'utente accede nuovamente alla pagina, potrebbe non inviare la richiesta alla tua applicazione in modo che l'utente pensi di aver preso un'azione, ma in realtà non lo ha fatto.

    
risposta data 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?

La risposta più semplice è "perché non è quello che GET significa".

Utilizzare GET per passare i dati per un aggiornamento è come scrivere una lettera d'amore e inviarla in una busta contrassegnata con "OFFERTA SPECIALE - AGIRE ORA!" In entrambi i casi, non dovresti essere sorpreso dal fatto che il destinatario e / o gli intermediari maneggiano male il tuo messaggio .

    
risposta data 02.03.2013 - 16:40
fonte
5

Per le tue CRUD operazioni in un'applicazione basata su database utilizza il seguente schema:

Usa HTTP GET per operazioni di lettura (SQL SELECT)

Usa HTTP PUT per operazioni di aggiornamento (SQL UPDATE)

Usa HTTP POST per creare operazioni (SQL INSERT)

Usa il DELETE HTTP per le operazioni di cancellazione (DELETE SQL)

    
risposta data 05.03.2013 - 22:43
fonte
0

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

Questo consiglio e tutte le risposte qui sono sbagliate. Ovviamente sono eccessivamente drammatico, le altre risposte sono eccellenti, ma credo che il consiglio esatto dovrebbe essere dato come:

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

Dire "mai" è troppo estremo, e anche se le altre risposte qui spiegano accuratamente perché si dovrebbe "raramente" farlo, ci sono alcuni scenari in cui è perfettamente ragionevole cambiare i dati con un GET. Un esempio è un collegamento per la verifica dell'e-mail di una tantum. In genere questi collegamenti contengono un GUID che, una volta effettuato l'accesso, dovrà modificare i dati. Se correttamente implementate, le successive richieste GET identiche verranno ignorate.

Questo è ovviamente un caso limite, ma certamente degno di nota.

    
risposta data 28.12.2015 - 17:45
fonte

Leggi altre domande sui tag