variable $_POST et bouton retour

Eléphant du PHP | 120 Messages

22 juil. 2015, 16:16

Bonjour à tous,
j'ai mis en place un module d'admin de gestion de site web pour modifier le contenu des pages de mon site. J'ai donc un formulaire de saisie, j'envoie les variables en $_POST à la page de mise à jour de la base, par exemple.
Le probleme, c'est que certains utilisateurs du module d'admin passent parfois par le bouton retour du navigateur au cours de leurs modifs, si bien que je me suis retrouvé quelques fois avec un chargement de la page contenant l'enregistrement en base sans que les utilisateurs arrivent de la page de saisie, donc les $_POST sont vides, et ca efface le contenu de cet enregistrement, je perds donc le contenu de toute la page...

Alors, au delà de leur dire de ne pas utiliser les boutons retour dans le module d'admin, j'aimerai sécuriser l'enregistrement pour éviter l'effacement. Je pensais me baser sur le fait que les $_POST soient vides, mais parfois certains champs sont vides... ou alors il faudrait controler que dans le cas où tous sont vides, alors c'est qu'il y a une soucis, on enregistre pas...mais ca me parait tordu comme processus.
je pensais regarder du coté de HTTP_REFERER pour vérifier que l'utilisateur arrive bien de ma page de saisie contenant le formulaire (et donc les $_POST ne sont pas vides) mais il parait que ca ne marche que si l'utilisateur l'autorise ?! Du coup, est vraiment la meilleure solution ?

Quel est selon vous la meilleure stratégie ? J'imagine que dans un module d'admin bien conçu, ce genre de problematique est monnaie courante ?...

merci de votre aide
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Mammouth du PHP | 688 Messages

22 juil. 2015, 16:48

un champ avec valeur unique dans le formulaire
test s'il existe une session pour ce champ
si c'est le cas
test si c'est une nouvelle valeur ou non; ajout en bdd selon le cas
si c'est pas le cas; ajout en bdd

ajout du champ en session si nécessaire

Eléphant du PHP | 120 Messages

22 juil. 2015, 17:54

qu'est ce que tu entends par valeur unique ? du genre je mets un champs hidden valeur fixe 1 à tous les coups juste pour tester si on vient bien de la page source ?
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Eléphant du PHP | 243 Messages

22 juil. 2015, 18:28

Tu dis que les champs sont vides.
Mais pourquoi ne pas mettre une sécurité du type :
.Si un des champs est vide
>Alors on annule l'envoi dans la BDD
À ce moment là, plus aucun ajout de ligne vide ne pourra avoir lieu.
"Nos études ont montré que la probabilité qu’un programme corrigé fonctionne comme avant la correction est seulement de cinquante pour cent"
~~Lorenzo Strigini

Mammouth du PHP | 688 Messages

22 juil. 2015, 18:44

avec une valeur fixe, il n'y a pas moyen de savoir, au second traitement du formulaire, si c'est le même formulaire resoumis avec les mêmes données, ou si c'est un second remplissage du formulaire.
un simple microtime() suffit.

Eléphant du PHP | 120 Messages

22 juil. 2015, 19:45

Tu dis que les champs sont vides.
Mais pourquoi ne pas mettre une sécurité du type :
.Si un des champs est vide
>Alors on annule l'envoi dans la BDD
À ce moment là, plus aucun ajout de ligne vide ne pourra avoir lieu.
je ne peux pas mettre ce genre de sécurité car certains champs peuvent etre vides... par contre tous les champs ne peuvent pas etre vides... alors dans ce cas il faudrait que je crée une regle qui vérifie si TOUS les champs sont vides
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Eléphant du PHP | 120 Messages

22 juil. 2015, 19:51

avec une valeur fixe, il n'y a pas moyen de savoir, au second traitement du formulaire, si c'est le même formulaire resoumis avec les mêmes données, ou si c'est un second remplissage du formulaire.
un simple microtime() suffit.
finalement, dans mon cas, peu importe que le formulaire soit re-soumis, du moment que les valeurs sont transmises...
mais dans mon schéma, le probleme c'est si l'utilisateur utilise le bouton retour du navigateur... prenons un exemple de parcours utilisateur :

1 : login module d'admin > 2 : accès au formulaire de la page à modifier > 3 : transmission des valeurs du formulaire en $_POST et enregistrement des modifs sur cette page finale > 4 : retour à la liste des pages disponibles > 5 : utilisation du bouton retour du navigateur et donc retour à la page 3 : sauf que ce coup ci les valeurs du formulaire en $_POST sont vides vu qu'elles ne sont pas transmises par la page 2 et donc enregistrement de valeur vide donc écrasement complet
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Eléphant du PHP | 120 Messages

22 juil. 2015, 19:54

A la rigueur, l'utilisation d'une valeur cachée du genre $cachée = 1 passée en $_POST entre l'étape 2 et 3, et qui serait testée à chaque fois qu'on arrive sur la page 3 (si la valeur existe alors j'enregistre toutes les autres $_POST dans la base).
Dans le cas d'un retour navigateur, on passe de la page 4 à la page 3, et donc la valeur cachée n'existe pas... et donc on ne fait rien
Ca pourrait etre une solution plus simple qu'un test pour savoir si TOUTES les valeurs sont vides...
non ?
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Eléphant du PHP | 243 Messages

22 juil. 2015, 19:57

alors dans ce cas il faudrait que je crée une regle qui vérifie si TOUS les champs sont vides
Et bien tu peux utiliser :
if (condition1 != "" && condition2 != "" && condition3 != "") {
    //On peut envoyer le formulaire
}
"Nos études ont montré que la probabilité qu’un programme corrigé fonctionne comme avant la correction est seulement de cinquante pour cent"
~~Lorenzo Strigini

Eléphant du PHP | 243 Messages

22 juil. 2015, 20:00

Où alors j'ai une autre proposition !
Sur ta page du formulaire, tu fais un envois par requête Ajax. En gros le navigateur va appeler une page (la page d'envoie) mais celle ci ne sera pas dans l'historique.
Ensuite, en fonction de la réponse de ta page php (celle qui est appelée et qui écrit les données), tu rediriges ou non vers une page.
Là tu n'auras plus le problème de retour.
"Nos études ont montré que la probabilité qu’un programme corrigé fonctionne comme avant la correction est seulement de cinquante pour cent"
~~Lorenzo Strigini

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 juil. 2015, 11:01

Bonjour,

Pourquoi ne pas utiliser le pattern PRG (Post Redirect Get) ? Le principe est qu'une fois que l'enregistrement du formulaire envoyé en post a été réalisé, tu rediriges l'utilisateur sur une nouvelle page via un header php (avec éventuellement les paramètres qui vont bien pour afficher d'éventuels messages de confirmation ou d'erreur).

Cette redirection se fait en GET vers une page qui ne traite pas le formulaire et qui n'a pas nécessité l'envoi d'un formulaire pour être affiché. Ainsi, lorsque l'utilisateur sollicite à nouveau cette page (via le bouton précédent du navigateur, la touche backspace du clavier, en farfouillant dans son historique, etc.), aucun formulaire n'est renvoyé et aucune demande de confirmation de renvoi des données n'est proposé par le navigateur. L'utilisateur arrive au mieux sur une page lui indiquant que les données qu'il avait envoyée ont été correctement enregistrées (ou pas), mais ne les renvoi pas :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 120 Messages

23 juil. 2015, 14:22

ok merci pour vos suggestions...
je vais les étudier une par une et ce qui est le plus simple et/ou le plus sûr dans mon cas ;-)
merci encore !
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

ViPHP
xTG
ViPHP | 7331 Messages

23 juil. 2015, 16:23

D'expérience après avoir lu ton souci je te recommande aussi le pattern PRG que te propres Ryle.
Cela répond parfaitement à la problématique. :)

Eléphant du PHP | 120 Messages

23 juil. 2015, 18:10

je vous avoue que, etant dans le forum php débutant, la technique du PRG Pattern est un peu confuse pour moi... j'ai commencé à faire des recherches sur le net, mais c'est encore pire lol : https://amethyste16.wordpress.com/2014/ ... ttern-prg/
faut que je cherche encore pour trouver des exemples d'implémentation simples... ;-)
si tu as un soucis en informatique, dis toi bien que quelqu'un d'autre l'a eu avant toi

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

23 juil. 2015, 18:21

Bonjour,

Voici un exemple trouvé sur Stackoverflow :
if ($_POST) {
   // Effectuer ici le traitement (ajout dans une bdd ou envoie de mail par exemple)
   // ...

   // Rediriger vers la page courante (ou une autre page si besoin)
   header("Location: " . $_SERVER['REQUEST_URI']);
   exit();
}
http://stackoverflow.com/a/4142969
Quand tout le reste a échoué, lisez le mode d'emploi...