web-dev-qa-db-fra.com

Pourquoi une demande GET ne devrait-elle pas modifier les données sur le serveur?

Partout sur Internet, je vois les conseils suivants:

Un GET ne devrait jamais modifier les données sur le serveur - utilisez une demande POST pour cela

Quelle est la base de cette idée?

Si je crée un service php qui insère des données dans la base de données et que je passe des paramètres dans la chaîne de requête GET, pourquoi est-ce faux? (J'utilise des instructions préparées pour prendre soin de l'injection SQL). Une demande POST est-elle en quelque sorte plus sûre?

Ou y a-t-il une raison historique à cela? Si oui, dans quelle mesure ces conseils sont-ils valables aujourd'hui?

115
Devdatta Tengshe

Ce n'est pas un conseil.

Un GET est défini de cette manière dans le protocole HTTP . Il est censé être idempotent et sûr .

Quant à savoir pourquoi - un GET peut être mis en cache et dans un navigateur, actualisé. Encore et encore et encore.

Cela signifie que si vous refaites le même GET, vous réinsérerez dans votre base de données .

Considérez ce que cela peut signifier si le GET devient un lien et qu'il est analysé par un moteur de recherche. Vous aurez votre base de données pleine de données en double.

Je suggère également de lire RI, adressabilité et utilisation de HTTP GET et POST .


Il y a aussi un problème avec préchargement de lien dans certains navigateurs - ils feront un appel à des liens de prélecture, même si cela n'est pas indiqué par l'auteur de la page.

Si, par exemple, votre déconnexion se trouve derrière un "GET", lié à partir de chaque page de votre site, les gens peuvent se déconnecter simplement en raison de ce comportement.

187
Oded

Chaque verbe HTTP a sa propre responsabilité. Par exemple GET, tel que défini par RFC

signifie récupérer toute information (sous la forme d'une entité) identifiée par l'URI de demande.

POST, d'autre part, signifie insérer ou plus formellement

La méthode POST est utilisée pour demander au serveur Origin d'accepter le
entité incluse dans la demande en tant que nouveau subordonné de la ressource
identifié par l'URI de demande dans la ligne de demande

Raisons pour que cela reste ainsi:

  • C'est très simple et fonctionne à l'échelle mondiale d'Internet depuis 1991
  • Respectez le principe de responsabilité unique
  • D'autres parties utilisent GET pour servir de moyen de recherche d'informations et d'exploration de données
  • GET est supposé être une opération sûre qui ne modifie jamais l'état de la ressource
  • Pour des raisons de sécurité, GET est en fait une lecture , tandis que POST est en fait une écrire
  • GET est mis en cache par les navigateurs, les nœuds du réseau, les fournisseurs de services Internet
  • À moins que le contenu ne change, GET vers la même URL doit renvoyer les mêmes résultats à tous les utilisateurs, sinon vous n'aurez aucune confiance dans le résultat renvoyé

Pour être complet et juste pour appliquer une utilisation correcte (source) :

  • GET les paramètres sont transmis dans le cadre de l'URL, qui est de petite taille et limitée à 256 caractères par défaut, avec certains serveurs prenant en charge plus de 4000 caractères. Si vous souhaitez insérer un long enregistrement, il n'existe aucun moyen légitime de transmettre ces données dans
  • Si vous utilisez une connexion Secure, ̶ tels que tLS, ̶ URL ne reçoit pas Encrypted, ̶ D'où tous les paramètres ̶G̶E̶T̶̶ ̶a̶r̶e̶ ̶t̶r̶a̶n̶s̶f̶e̶r̶r̶e̶d̶ ̶p̶l̶a̶i̶n̶ ̶t̶e̶x̶t̶. L'URL est réellement cryptée avec TLS, donc TLS est très bien.
  • L'insertion de données binaires ou de caractères non ASCII à l'aide de GET n'est pas pratique
  • GET est réexécuté si un utilisateur appuie sur un bouton Retour dans un navigateur
  • Certains robots plus anciens peuvent ne pas indexer les URL avec un ? signe à l'intérieur
24
oleksii

EDIT: Avant, j'ai dit POST vous aide à vous protéger contre CSRF mais c'est faux. Je n'y ai pas réfléchi correctement. Vous devez exiger un jeton caché unique de portée de session dans toutes vos demandes de changement données à protéger contre CSRF.

Au début d'Internet, il y avait des accélérateurs de navigateur. Ces programmes commenceraient à cliquer sur les liens d'une page pour mettre en cache le contenu. Google Web Accelerator était l'un de ces programmes. Cela pourrait faire des ravages sur une application qui apporte des modifications lors d'un clic sur un lien. Je ferais l'hypothèse qu'il y a encore des gens qui utilisent un logiciel accélérateur.

Les serveurs proxy et les navigateurs mettront en cache les demandes GET. Ainsi, lorsque l'utilisateur accède à nouveau à la page, il peut ne pas envoyer la demande à votre application.

10
Sarel Botha

Si je crée un service php qui insère des données dans la base de données et que je passe des paramètres dans la chaîne de requête GET, pourquoi est-ce faux?

La réponse la plus simple est "parce que ce n'est pas ce que signifie GET".

Utiliser GET pour transmettre les données d'une mise à jour, c'est comme écrire une lettre d'amour et l'envoyer dans une enveloppe marquée "OFFRE SPÉCIALE - AGISSEZ MAINTENANT!" Dans les deux cas, vous ne devriez pas être surpris que le destinataire et/ou les intermédiaires manipulent mal votre message.

8
Nathan Long

Pour vos opérations CRUD dans une application centrée sur la base de données, utilisez le schéma suivant:

Utiliser HTTP GET pour les opérations de lecture (SQL SELECT)

Utiliser HTTP PUT pour les opérations de mise à jour (SQL UPDATE)

Utilisez HTTP POST pour les opérations de création (SQL INSERT)

Utiliser HTTP DELETE pour les opérations de suppression (SQL DELETE)

5
user83191

Un GET ne devrait jamais modifier les données sur le serveur - utilisez une demande POST pour cela

Ce conseil et toutes les réponses ici sont faux. Évidemment, je suis trop dramatique, les autres réponses sont excellentes, mais je pense que les conseils exacts devraient être donnés comme suit:

Un GET devrait rarement modifier les données sur le serveur - utiliser une demande POST pour cela

Dire "jamais" est trop extrême, et bien que les autres réponses ici expliquent précisément pourquoi vous devriez "rarement" le faire, il existe certains scénarios où il est parfaitement raisonnable de modifier les données avec un GET. Un exemple est un lien de vérification d'e-mail à usage unique. En règle générale, ces liens contiennent un GUID qui, lorsqu'ils seront accédés, devra modifier les données. S'ils sont correctement mis en œuvre, les requêtes GET identiques suivantes seront ignorées.

Il s'agit évidemment d'un cas Edge, mais il vaut certainement la peine d'être noté.

0
TTT