Bonjour,

Je suis en train de faire un site, et j'aimerai que l'utilisateur aie la possibilité de changer son mot de passe.

J'ai donc fais un formulaire dans le profile du user :

<form method="post" action="admin/insert/mdp.php">
            <tr>
                <td>
                    <label>Nouveau mot de passe</label>
                    <input type="password" name="new_pass">
                </td>
            </tr>
            <tr>
                <td>
                    <label>Confirmation du mot de passe</label>
                    <input type="password" name="new_pass_conf">
                </td>
            </tr>
            <tr>
                <td>
                    <label>Ancien mot de passe</label>
                    <input type="password" name="pass_old">
                </td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" class="btn btn-bleu" value="changer de mot de passe" name="submit"></td>
            </tr>
    </form>

et dans ma page mdp.php j'ai mis ça :

<?php
header('Location:./../../index.php');
    require "./../../class/config.php";
    mysql_connect(DB_HOST,DB_LOGIN,DB_PASS);
    mysql_select_db(DB_BDD);

    extract($_POST);

// tu récupère l'ancien mot de passe dans la bdd
$sql = mysql_query('SELECT password FROM users WHERE id = " . $users[id] .');
list($password) = mysql_fetch_array($sql);
// tu compare si le nouveau passe correspond à l'ancien
if ($new_pass == $new_pass_conf)
{
    // tu encrypte l'ancien mot de passe du formulaire pour le comparer à celui de ta bdd
    $pass_old = md5($pass_old);
    //tu vérifie si il sont identique
    if ($password == $pass_old)
    {
        //si oui tu update et encrypte le nouveau mot de passe dans la bdd
        $pass = md5($new_pass);  
        $query = mysqli_query('UPDATE users SET password = '" . $pass . "' WHERE id = " . $users[id] .');
        echo "mot de passe changé";
    }
    else
    {
        echo "Ancien mot de passe non valide";
    }
}
else
{
    echo "Mot de passe de confirmation incorrecte";
}   

?>

Il manque surement quelque chose car ça ne me change pas le mot de passe, et aussi mon header location ne fonctionne pas, et je n'arrive pas à comprendre où est l'erreur!

help ?

9 réponses


La vite fait je dirais que c'est la requete sql qui ne va pas (mais y a pas que ça... on utilise plus mysql_query... ou connect mais on passe par PDO...) ta concaténation n'est pas bonne :

$sql = mysql_query('SELECT password FROM users WHERE id = " . $users[id] .');

ton $user['id'] ne doit pas être entouré de ' :

$sql = mysql_query("SELECT password FROM users WHERE id = " . $users[id]);

Bon après c'est surement pas ça j'ai juste regardé vraiment très vite fait ton code.

  • Du fait de l'utilisation de extract() et de mysql_query, il est possible de contrôler $users[id] qui est utilisé dans la requête sans être « nettoyé » avant, ce qui mène donc à une injection SQL. Pars sur PDO ;-)

  • La comparaison entre les deux md5 n'est pas correcte, tu utilises == mais il faudrait au moins utiliser === pour aussi compararer le type (cf. http://blog.astrumfutura.com/2015/05/phps-magic-hash-vulnerability-or-beware-of-type-juggling/, par exemple).

  • Le require "./../../ est un peu hasardeux, tu devrais préférer l'utilisation de __DIR__ pour mieux t'y retrouver des tes répertoires.

  • Pour ton header, tu dois utiliser des adresses absolues (cf. http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30). Et tu dois die() ou exit() après avoir appelé la fonction — dans tous les cas, ça ne sert à rien d'afficher quelque chose après le header, si il est redirigé, il ne le verra jamais.

  • La concaténation $sql = mysql_query('SELECT password FROM users WHERE id = " . $users[id] .'); est étrange. Je pense plutôt à un $sql = mysql_query('SELECT password FROM users WHERE id =' . $users[id]);.

  • D'où vient $users[id] ? Il n'est pas présent dans ton formulaire et la variable n'existe donc pas - ni $users ni $id (comportement normal de extract().

  • Ça ne changera rien au fait que ça ne marche pas, mais tu devrais plutôt utiliser $_POST directement…

mirael86
Auteur

J'ai récupéré le code sur internet j'avoue!
Je ne connais pas trop PDO et mysqli_ ... et je suis débutant en PHP!! Mais ça n'excuse rien je sais!!

Quelqu'un peut me dire alors ce que ça donnerai en PDO ? j'en demande peut-être un peu trop mais j'ai vraiment du mal à finaliser un site sur lequel je me suis engagé... j'ai contourné pas mal de problème en faisant du rafistolage, mais je suis bloqué à sur le changement de mail... c'est un truc compliqué en temps normal ou c'est moi qui suis vraiment une quiche ?? lol

mirael86
Auteur

Merci à tous... je vais regarder le tuto que me propose sudovim!! :)

En fonction du temps que tu as, revois même un bon cours de PHP depuis le début (http://www.phptherightway.com/), parce que sinon tu risque de perdre un temps fou à bricoler sans comprendre et tu n'auras jamais fini à temps… Ou alors sous-traite :^

mirael86
Auteur

Bonsoir,

J'ai réalisé quelque modifs sur mon code, en m'appuyant sur les commentaires de chacun.

  • J'ai modifié mon header location en mettant un exit()
  • je n'utilise plus les variables user et id
  • Pour tester je ne hash pas le mot de passe en md5 (ou sha1)

De plus, je fais une validation supplémentaire par l'email :

Voilà pour mon code html

<form method="post" action="admin/insert/mdp.php">
            <tr>
                <td>
                    <label>Entrez votre adresse mail</label>
                    <input type="text" name="mail">
                </td>
            </tr>
            <tr>
                <td>
                    <label>Ancien mot de passe</label>
                    <input type="password" name="pass_old">
                </td>
            </tr>
            <tr>
                <td>
                    <label>Nouveau mot de passe</label>
                    <input type="password" name="new_pass">
                </td>
            </tr>
            <tr>
                <td>
                    <label>Confirmation du mot de passe</label>
                    <input type="password" name="new_pass_conf">
                </td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" class="btn btn-bleu" value="Valider" name="Submit"></td>
            </tr>
    </form>

Voilà pour la validation en php :

<?php
header('Location: ' . $_SERVER['HTTP_REFERER']);
exit();

  if (isset($_POST['Submit']) && $_POST['Submit'] == 'Valider') {
    $mail = $_POST['mail'];
    $new_pass = $_POST['new_pass'];
    $pass_old = $_POST['pass_old'];
    $new_pass_conf = $_POST['new_pass_conf'];

    $base = mysql_connect ('localhost', 'root', 'root');
            mysql_select_db ('tuto', $base);

// tu récupère ancien mot de passe dans la bdd

$sql = mysql_query("SELECT password FROM users WHERE mail = '" . $address ."'");
list($password) = mysql_fetch_array($sql);

// tu compare si le nouveau passe correspond à l'ancien
if ($new_pass == $new_pass_conf)
{

    //tu vérifie si il sont identique
    if ($password == $pass_old)
    {
        //si oui tu update et encrypte le nouveau mot de passe dans la bdd

        $pass   = $new_pass;  

        $query  = mysql_query("UPDATE users SET password = '. $pass .'  WHERE mail = '". $address ."'");

        echo "Merci, le mot de passe à été changé.";
    }
    else
    {
        echo "Ancien mot de passe non valide";
    }
}
else
{
    echo "Mot de passe de confirmation incorrect, recommencez SVP";
}
}
?>

Je vous remercie pour l'aide que vous pourrez m'apporter! J'aimerai vraiment réussir à changer les mots de passe !

Premier soucis que je fois : tu exit() après ton header : c'est bien, mais il ne faut pas mettre ça au tout début du code, sinon le reste n'est pas exécuté ;-) Il faut le mettre à la toute fin !

mirael86
Auteur

Merci à vous pour votre soutient ! :)

@flan : en fait, je ne comprends pas trop ce que tu me dis parce que dans mes autres insertions à la base, je mets mon header en début de code, et je n'ai pas de problème! ça me lit bien le reste de mon code, et ça me renvoit pas à la page voulut! Par contre, en testant de le mettre à la fin, il me renvoit Ancien mot de passe non valide.

Est-ce-que tu penses que c'est uniquement lié à mon hashage en md5 qui n'est pas encore fait ?

@sudovim Pour le header ("location..., c'est pour me renvoyer à la même page, car mon utilisateur est forcément connecté s'il accède à la page profile.php (là où il peut modifier son mdp).

Sinon, oui j'avais oublié de mettre les === comme tu me l'avais déjà conseillé :)

Aussi je me posais la question de savoir si la concaténation était bien faite ici :

$query  = mysql_query("UPDATE users SET password = '. $pass .'  WHERE mail = '". $address ."'");

Je fais tout ça et je vous tiens au courant!

Bonjour.
Alors, pour commencer, pourquoi ta varaiable $mail devient tout d'un coup $address ?
Ensuite, ce serait peut-être judicieux de vérifier si ta requête SELECT te retourne un résultat ou non avant de continuer le traitement.
De toute manière, vu ton erreur sur le nom de la variable, ça m'étonnerait que tu aies un retour de données et un enregistrement en base de données.
C'est d'ailleurs pour ça que tu tombes dans la condition Ancien mot de passe non valide.