PHP: empêche un traitement d'être traité de manière accidentelle lorsque vous appuyez sur le bouton Retour

StackOverflow https://stackoverflow.com/questions/1646812

Question

Quel est le meilleur moyen d'empêcher le retraitement d'un formulaire lorsqu'un utilisateur clique sur le bouton Précédent?

Je suis le Publier / Rediriger / Obtenir le modèle , donc Je n'ai pas de problème si vous appuyez sur F5, mais le bouton Précédent offre quand même la possibilité de soumettre à nouveau le formulaire. Si ce formulaire est une page de traitement de carte de crédit, c'est mauvais.

Cette question a été posée un peu ici , mais la formulation et les réponses étaient de mauvaise qualité et ne portaient pas précisément sur ce problème.

J'ai form.php qui se soumet à lui-même. S'il n'y a pas eu d'erreur dans les données d'entrée lors de la soumission, l'utilisateur est redirigé vers form_thanks.php. Rattraper (et "envoyer" ou "soumettre à nouveau") une fois, soumet à nouveau form.php (BAD!), Puis les ramène à form_thanks.php.

Veuillez également inclure des solutions n'impliquant pas, si possible, l'utilisation de sessions.

Était-ce utile?

La solution 2

Cela devrait être fait avec un jeton à usage unique ou un nonce . Le php / serveur doit inclure ce jeton dans un champ de formulaire masqué.

Il devrait stocker une liste de tous les jetons récents et à chaque fois qu'un formulaire est soumis, il devrait vérifier si le jeton figure dans la liste des jetons valides récents.

S'il ne figure pas dans la liste, ne retraitez pas le formulaire.
S'il se trouve dans la liste, traitez le formulaire et supprimez le jeton de la liste.

Les jetons peuvent être gérés dans des sessions ou simplement dans une simple table de base de données sans sessions. Les jetons doivent cependant être spécifiques à l'utilisateur.

C’est également le moyen recommandé d’éviter les attaques de CSRF .

Autres conseils

Je le ferais différemment. Mettez une entrée masquée avec une chaîne aléatoire comme valeur et, lorsqu'elle est soumise, stockez cette chaîne aléatoire dans une session. Configurez un simple contrôle pour voir s’ils l’ont déjà posté et s’ils n’acceptent pas l’entrée.

Juste penser à voix haute ici. Mais qu’en est-il de la variation post / redirect / get où l’obtention finale n’est pas réellement l’obtention finale;) mais plutôt, elle retourne toujours automatiquement à la page vraiment finale, de sorte que si l’utilisateur clique sur le bouton Précédent, il retourne de retour d'où ils sont venus?

EDIT:

Ok, en tenant compte du commentaire du PO, voici une autre idée. L'URL de la soumission du formulaire peut être créé pour exiger un paramètre valide pour un seul usage. Ce jeton serait généré (à l'aide de MD5 ou d'un tel outil) avant la soumission du formulaire et pourrait être stocké dans une base de données (en réponse à la suggestion de quelqu'un d'autre, vous avez demandé une solution sans utiliser de sessions). Une fois le formulaire traité, ce jeton serait alors signalé dans la base de données comme ayant déjà été utilisé. Ainsi, lorsque la page est renvoyée avec le même jeton, des mesures peuvent être prises pour empêcher la nouvelle soumission des données du formulaire au serveur.

Réponse tardive, mais on pourrait éviter le traitement en utilisant une solution basée sur AJAX; l'inclusion d'un nonce dans ce schéma de traitement ne poserait pas de problème, mais en utilisant une requête asynchrone qui, en cas de succès, redirige l'utilisateur, les requêtes ne sont pas répétées en rafraîchissant, en appuyant à nouveau ou en cliquant sur le bouton.

Il est également facile de mettre en place un mécanisme qui empêche le bouton d’être appuyé deux fois ou d'être "verrouillé". si quelque chose s'est passé lors de la demande en incorporant dans le gestionnaire de la demande (niveau élevé avec PrototypeJS ou jQuery ou niveau bas avec votre fonction handrolled) les mécanismes pour activer et désactiver le bouton lorsque la demande est terminée et se déclenche, respectivement.

Je trouve que back apportera le formulaire à l'état qu'il était avant la redirection de la page. Si tel est le cas, avez une entrée / variable masquée ou quelque chose qui commence par la valeur true, puis une fois le formulaire soumis, et si la valeur est true, remplacez-la par false, puis soumettez, sinon renvoyez false

Essayez ceci:

<SCRIPT type="text/javascript">
    window.history.forward();
</SCRIPT>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top