IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Empecher le renvoi d'un second formulaire identique


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 67
    Points : 21
    Points
    21
    Par défaut Empecher le renvoi d'un second formulaire identique
    Salut à tous ! C'est encore moi !

    Voilà je travaille sur un formulaire d'inscription très simple dont voici la requete permettant l'inscription dans la BDD :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?php
    	try {
    		//On se connecte à MySQL
    		$bdd = new PDO('mysql:host=localhost;dbname=noxads', 'root', '', array (PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
    	}
    	catch(Exception $e) {
    		//En cas d'erreur, on affiche un message et on arrête tout
    		die('Erreur : '.$e->getMessage());
    	}
     
    	if (array_key_exists('login', $_POST) AND $_POST['login'] != "" AND array_key_exists('password', $_POST) AND $_POST['password'] != "") {
    		$req = $bdd->prepare('INSERT INTO client(login, password) VALUES(:login, :password	)');
    		$req->execute(array(
    		'login' => htmlspecialchars($_POST['login']),
    		'password' => htmlspecialchars(md5($_POST['password']))
    		));
    	}
    Je voudrais donc empecher l'utilisateur de renvoyer un second formulaire, du moins de recharger la page puis d'insérer un formulaire autant de fois qu'il veut. Je peux faire ca avec un header pour rediriger mais l'utilisateur peut etre très ingénieux...j'ai testé de mettre une variable de session, mais cela ne change rien...quelqu'un peut m'aider ?

    Merci beaucoup

  2. #2
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Le principe est simple, il suffit de lancer en 1er (donc avant l'insertion) une requête SQL pour vérifier si le couple login/passe existe dans la Bdd.

    Ensuite, 2 cas possible :
    - SI le couple existe ALORS on n'effectue pas d'insertion
    - SINON on effectue l'insertion

    Une requête SQL du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT COUNT(*) AS total
    FROM client
    WHERE login = :login
    AND password = password)
    Ensuite suffit de récupérer la valeur "total" pour l'exploiter dans la condition vu précédemment.


    Petite parenthèse au passage, il n'y a pas lieu d'appliquer des htmlspecialschar() pour un login/pass, c'est une sur-couche de code inutile, ça ne protègera pas plus pas moins contre une éventuelle injection SQL.
    Tu utilises PDO avec une requête préparée, cela suffit car c'est ça qui te protègera contre ce type d'attaque.

    Ce n'est que si tu venais à afficher le login ou/et mot de passe dans un page HTML ou là cette fonction sera utile.
    En somme, ne mélange pas tout pour ce qui est de la sécurité ou autre.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 67
    Points : 21
    Points
    21
    Par défaut
    Effectivement, j'ai oublié que j'affichais pas tout ça ^^

    Par contre je n'ai pas vraiment compris ta méthode...

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Je suis d'accord avec RunCodePhp.

    Actuellement, lorsque tu valides ton formulaire, tu appelles directement ta fonction insert :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (array_key_exists('login', $_POST) AND $_POST['login'] != "" AND array_key_exists('password', $_POST) AND $_POST['password'] != "") {
    		$req = $bdd->prepare('INSERT INTO client(login, password) VALUES(:login, :password	)');
    		$req->execute(array(
    		'login' => htmlspecialchars($_POST['login']),
    		'password' => htmlspecialchars(md5($_POST['password']))
    		));
    	}
    Sauf que en effet comme tu le dit, si la personne revalides le formulaire, ça va l'ajouter une seconde fois.

    Le principe c'est qu'avant d'effectuer cette requête, il faut vérifier que l'utilisateur n'existe pas. Pour cela que la requête de RunCodePhp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT COUNT(*) AS total
    FROM client
    WHERE login = :login
    AND password = password)
    permet de vérifier si l'utilisateur existe déjà (si tu reçois 1 c'est que le user existe, si tu récupères 0, c'est qu'il a déjà été inséré).

    En fonction de ce résultat, soit tu insères, soit tu affiches un message d'erreur.

    A ta place, je ferais une page formulaire, et une page traitement. Ainsi sur la page traitement, soit tu affiches "Votre compte à bien été créé", soit tu affiches "Cet utilisateur existe déjà" avec un lien de retour vers le formulaire. Ainsi les POST seront vidés également.
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  5. #5
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 021
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 021
    Points : 2 278
    Points
    2 278
    Par défaut
    Du détail mais tu devrais plutôt utiliser isset(), plus rapide et surtout :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $_POST['login'] = null;
    array_key_exists('login', $_POST) // retourne true
    (d'un autre côté null == "" donne true donc ton 2e test résout le problème potentiel mais bon...)
    Vive les roues en pierre

Discussions similaires

  1. Réponses: 9
    Dernier message: 22/11/2006, 19h01
  2. [Conception] Formulaires identiques pour INSERT et UPDATE
    Par MiJack dans le forum PHP & Base de données
    Réponses: 15
    Dernier message: 16/06/2006, 11h34
  3. Empecher l'enregistrement direct dans un formulaire
    Par eddyG dans le forum Sécurité
    Réponses: 2
    Dernier message: 09/06/2006, 21h10
  4. Réponses: 4
    Dernier message: 25/05/2006, 21h05
  5. ouvrir plusieurs formulaires identiques
    Par Australia dans le forum Access
    Réponses: 5
    Dernier message: 21/04/2006, 11h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo