2010-07-22 5 views
1

J'ai passé des semaines à travailler sur la double protection de soumission sur mes formulaires. Straightup, la méthode de session de stockage des jetons ne fonctionne pas. Les sessions fonctionnent bien pour un rafraîchissement de la page ou pour quelqu'un qui remonte son histoire ... mais le double classique en cliquant sur le bouton à plusieurs reprises ne peut pas être évité en utilisant des sessions.Méthode de jeton sur les formulaires, double Envoyer

Je pense que le script ne peut pas vérifier/écrire/supprimer des sessions assez rapidement pour intercepter l'erreur lorsque plusieurs clics sont traités en millisecondes les uns des autres.

Existe-t-il une autre méthode côté serveur pour éviter ce problème?

Répondre

3

Il semble que vous ayez besoin d'un magasin de jetons indépendant capable d'éviter les conditions de course. Pour que cela fonctionne plusieurs solutions sont disponibles, l'une des plus faciles à implémenter serait:

  • Stockez le jeton dans une base de données, avec les champs (tokencode, claimid).
  • Lors de la réception, définissez un claimid à microtime(), peut-être même un ID de processus, ou hachage, tant qu'il est très sûr d'être unique dans des processus similaires démarrés à un moment donné les uns des autres.
  • Essayez de réclamer le jeton: UPDATE tokens SET claimid = <id> WHERE tokencode=tokencode AND claimid IS NULL
  • Nombre de lignes modifiées de l'instruction précédente (ou sélection).
  • Si une ligne a changé et/ou a votre microtime() 'd claimID: vous êtes le gagnant, passez à l'action
  • Si rien n'a changé ou le jeton a le mauvais claimID l'action ne sera pas prise.
+0

Monsieur, vous êtes bon. Cela semble fonctionner. J'ai rétabli la vérification des jetons dans ma classe de formulaires, mais j'ai utilisé la base de données au lieu des sessions. Je fais une légère variante de ce que vous avez suggéré - table avec id/token/used, insérer une ligne avec un token unique et used = false au début du formulaire, vérifier si la ligne est utilisée pour soumettre, et mettre à jour la ligne avec used = true . – swt83

+1

Votre altération supprime beaucoup d'effort de l'atomicité: n'attendez pas de mettre l'habitude à vrai, et revendiquez-le avec un identifiant unique. Dans les 5ms entre votre vérification et la mise à vrai dire environ 10 autres processus ont peut-être venir. Certes, moins de chance alors toute une session écrire/charger, mais quand même. – Wrikken

+0

J'apprécie cette différence et ai fait le changement. Merci beaucoup pour votre aide. – swt83

Questions connexes