Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

J'ai suivi le tuto de Grafikar sur la refactorisation de l'espace membre.
Page confirm.ph

<?php

 require_once "../class/bootstrap.php"; 

$db = App::getDatabase(Session::getInstance());

if(App::getAuth()->confirm($db, $_GET['id'], $_GET['token'], Session::getInstance())) {
    Session::getInstance()->setFlash('success', "Votre compte a été validé");
    App::redirect('account.php');
} else {
    Session::getInstance()->setFlash('danger', "Ce token n'est plus valide");
    App::redirect('login.php');

Page Auth.php

<?php

/**
 * Class Auth
 */
class Auth {
    private $options = [
        'restriction_msg' => "Vous devez vous connecter pour accéder à cette page !",
    ];
    private $session;

    /**
     * @param $session
     * @param array $options
     */
    public function __construct($session, $options = []) {
        $this->options = array_merge($this->options, $options);
        $this->session = $session;
    }

    public function hashPassword($password) {
        return password_hash($password, PASSWORD_BCRYPT);
    }

    /**
     * @param $db
     * @param $username
     * @param $password
     * @param $email
     */
    public function register($db, $Nom, $Prenom, $Age, $mail, $Password){
        $Password = $this->hashpassword($Password);
        $token = str::random(60);

        $db->query('INSERT INTO Users SET Nom = ?, Prenom = ?, Age = ?, rang_id = 1, mail = ?, Password = ?, confirmation_token = ?', [
            $Nom, 
            $Prenom, 
            $Age, 
            $mail, 
            $Password, 
            $token  
        ]);

        $users_id = $db->lastInsertId();
        $mail = strip_tags($mail);

        $header = "From : ".$mail;
        $sujet = "Confirmation de votre mail";
        $message = "Afin de valider votre compte, merci de cliquer sur ce lien\n\n".$_SERVER['.$_SERVER_NAME']."/sitejsp1/membres/confirm.php?id=".$user_id."&token=".$token;

        mail($mail, $sujet, $message, $header);
    }

    /**
     * @param $db
     * @param $user_id
     * @param $token
     * @return bool
     */
   public function confirm($db, $user_id, $token) {
        $user = $db->query('SELECT * FROM users WHERE id = ?', [$user_id])->fetch();

        if ($user && $user->confirmation_token == $token) {
            $req = $db->query('UPDATE users SET confirmation_token = NULL, confirmed_at = NOW() WHERE id = ?', [$user_id]);

            $this->session->write('auth', $user);

            return true;
        }

        return false;
    }

    /**
     * function restrict
     */
    public function restrict(){
        if (!$this->session->read('auth')){
            $this->session->setFlash('danger', $this->options['restriction_msg']);

            header('Location: login.php');
            exit();
        }
    }

    /**
     * @return bool
     */
    public function user() {
        if (!$this->session->read('auth')) {
            return false;
        }
        $this->session->read('auth');
    }

    /**
     * @param $user
     */
    public function connect($user) {
        $this->session->write('auth', $user);
    }

    /**
     * @param $db
     */
    public function connectauto($db){
         if (isset($_COOKIE['remember']) && !$this->user()){
            $remember_token = $_COOKIE['remember'];
            $parts = explode('==', $remember_token);
            $user_id = $parts[0];

            $user = $db->query('SELECT * FROM users WHERE id = ?',[$user_id])->fetch();

            if($user) {
                $expected = $user_id."==".$user->$remember_token($user_id.'blackshadow');
                if ($expected == $remember_token){
                    $this->connect($user);
                    setcookie('remember', $remember_token, time()+60*60*24*7);
                } else {
                    setcookie('remember', NULL, -1);
                }
            } else {
                setcookie('remember', NULL, -1);
            }
        }
    }

    /**
     * @param $db
     * @param $Nom
     * @param $password
     * @param bool $remember
     */
   public function login($db, $mail, $password, $remember = false) {
        $user = $db->query('SELECT * FROM users WHERE mail AND confirmed_at IS NOT NULL ', ['mail' => $mail])->fetch();

         if( !empty($user) && password_verify($password, $user->password)){
            $this->connect($user);

            if ($remember){
                $this->remember($db, $user->id);
            }
            return $user;
        } else {
            return false;
        }
    }

    /**
     * @param $db
     * @param $user_id
     */
    public function remember($db, $user_id) {
        $remember_token = Str::random(60);
        $db->query('UPDATE users SET remember_token = ? WHERE id = ?', [$remember_token, $user_id]);
        setcookie('remember', $user_id.'=='.$remember_token($user_id.'blakshadow'), time()+60*60*24*7);
    }

    public function logout() {
        setcookie('remember', NULL, -1);
        $this->session->delete('auth');
    }

    public function resetPassword($db, $mail) {
        $user = $db->query('SELECT * FROM users WHERE mail = ? AND confirmed_at IS NOT NULL', [$mail])->fetch();
        if ($user){
            $reset_token = Str::random(60);
            $db->query('UPDATE users SET reset_token = ?, reset_at = NOW() WHERE id = ?', [$reset_token, $user->id]);

            $header = "From : ".$mail;
            $sujet = "[http://".$_SERVER['SERVER_NAME']."/] Reset du password";
            $message = "Pour réinitialiser votre mot de passe, merci de cliquer sur ce lien\n\n".$_SERVER['SERVER_NAME']."/sitejsp1/membres/reset.php?id={$user->id}&token=".$reset_token;

            mail($mail, $sujet, $message, $header);

            return $user;
        }
        return false;
    }

    public function verifResetToken($db, $user_id, $token) {
        return $db->query("SELECT * FROM users WHERE id = ? AND reset_token = ? AND reset_at > DATE_SUB(NOW(), INTERVAL 30 MINUTE)",[$user_id, $token])->fetch();
    }
}

Page str.php

<?php

/**
 * Class Str
 */
class Str {
    /**
     * @param $length
     * @return string
     */
    static function random($length){
        $alphabet = "1234567890azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN";
        return substr(str_shuffle(str_repeat($alphabet, $length)), 0, $length);
    }
}

Page App.php

<?php

class App{

    /**
     * @var null
     */
    static $db = null;

    /**
     * @return Database|null
     */
    static function getDatabase(){

        if(!self::$db){
            self::$db = new Database('root', '', 'sitejsptest');

        }

        return self::$db; 
    }

     /**
     * @return Auth
     */
    static function getAuth(){
        return new Auth(
            Session::getInstance(),
            ['restriction_msg' => 'Accès interdit !']
        );
    }

    /**
     * @param $page
     */
    static function redirect($page) {
        header('Location: '.$page);
        exit();
    }
}

Ma BDD

<a href="http://www.casimages.com/i/180324020534772597.jpg.html" title="BDD">Lien vers mon image</a>

Ce que je veux

Reussir à valider l'inscription.
Merci de votre aide!!

Ce que j'obtiens

Impossible de valider l'inscription, je n'ai pas d'erreur php ou de la BDD proprement dit, j'ai juste le message " ce token n'est plus valide"
du coup je sais pas si j'ai d'autre erreur pour l'instant!!

Apres verification les 2 token sont identique.
Le lien que je recois dans le mail
/sitejsp1/membres/confirm.php?id=&token=hn82esL4YxfbBJ8oZnajUypbO348s6kZ13P9auDO08ShFCzOyJWqbyHkLdr4

Le token en BDD: hn82esL4YxfbBJ8oZnajUypbO348s6kZ13P9auDO08ShFCzOyJWqbyHkLdr4

13 réponses


Lartak
Réponse acceptée

Bonjour.
Si tu lis bien ton code, tu remarqueras que tu as plusieurs erreurs, ou tout du moins, une erreur qui en cause plusieurs.
Dans ta méthode register, tu définis une variable users_id, mais dans ton mail, tu utilises une variable user_id, soit une variable qui n'est pas définie et ensuite tu te base sur la valeur du paramêtre id qui est par conséquence vide, tu ne peux donc pas avoir de retour de données de ta BDD.
En plus de ça, dans le dernier code que tu nous montres concernant ta méthode confirm, tu fais un SELECT avec en condition le token, alors que tu passes en paramêtre l'ID de l'utilisateur, ce qui n'est absolument pas logique.
Autre chose aussi, SERVER_NAME n'est pas une variable, mais une clé de la variable $_SERVER, il te faut donc remplacer $_SERVER['.$_SERVER_NAME'] par $_SERVER['SERVER_NAME'].
Pour finir, ta condition dans ta page account.php est totalement fausse, c'est à se demander si tu comprends vraiment ce que tu codes, où si tu ne fais que recopier du code que tu trouves.
Si c'est le second cas, je te conseille fortement de réétudier le PHP depuis ses bases.

Je n'ai pas vu la vidéo mais je remarque que tu passes 4 arguments à la méthode confirm alors qu'elle n'en accepte que 3 !!!

Bonsoir,
Merci Huggy pour ta reponse mais comment ca 4 arguments?

Sa fait 3-4 jours que je galere, je pense que je me melange les pinceaux!! LOL

J'ai modifier la fonction confirm :

 public function confirm($db, $user_id, $token) {
        $user = $db->query('SELECT * FROM users WHERE id = ?', [$user_id])->fetch();

par

public function confirm($db, $user_id, $token) {
        $user = $db->query('SELECT id FROM users WHERE confirmation_token = ?', [$user_id])->fetch();

        if ($user && $user->confirmation_token == $token) {
           $req = $db->query('UPDATE users SET confirmation_token = NULL, confirmed_at = NOW() WHERE id = ?', [$user_id]);
            $this->session->write('auth', $user);
            return true;
        }
        return false;
    }

Maintenant il me valide le token et me connect youpi!!! sauf que normalement dans ma BDD le confirmation_token devrai passer a NUL et le confirmed_at devrait afficher la date de validation helas les deux reste à NUL resultat des que je me deconnecte, je ne peux plus me connecter. Une idée? merci de votre aide!!

Euh non !!! tu peux pas comparer un token avec un user_id, garde ta requête comme elle était.

Pour les 4 arguments, dans la page confirm.php tu as ça

if(App::getAuth()->confirm($db, $_GET['id'], $_GET['token'], Session::getInstance())) {
...

tu passes bien la session en 4em argument (voir la video vers 58')
mais c'est inutile car dans la methode confirm la session fait partie de la classe ($this->session)
il faut revoir la video ou bien faire un choix

Euh mais quand je garde le requete d'origine j ai droit a " ce token n'est plus valide"
Dans la video c'est comme ca de memoire?! ou j enleve Session::getInstance ???

Regarde du coté des dates...
Tu fais un select avec une date > Now()...
Si ce n'est plus valable c'est que la durée d'expiration est dépassée...

mais je n' ai pas de delai d 'expiration!! enfin je crois pas!!

Bonsoir,

Personne a une idée? svp help me

J' ai toujours mon probleme impossible de valider le token par mail
Ou j'arrive a le valider mais aucune modification en BDD

merci de votre aide!!

Est ce que tu as essayé tes requetes en direct, juste pour voir si c'est ton code PHP ou tes requetes ?
Tu n'as pas d'erreurs d'execution des requetes ?
Après chaque update, que disent les valeurs de ta base de donnée ? si c'est vide...
Soit ta requete n'est pas bonne.. soit... as tu un auto commit dans ta base ou faut il faire un commit ?

Bonsoir,

mes requetes en direct? je n'ai aucune erreur c'est bien la le souci lol et quand je clique sur le lien de validation la BDD ne se s'update pas !!
Un commit ? je suis debutant en php et BDD.

Merci de ton aide

Moi quand mes requetes ne font pas ce que j'attend, j'essaye de passer par .. phpmyadmin par exemple, juste pour voir si... L'ID est bien trouvé, si les parametres sont bien entrés.. pas de souci de ' ou de " ou de date ou de probleme de typage (String / Integer / Date...
Ce que tu peux faire c'est un debug/vardump de ta requete apres l'avoir construite pour voir ce qui va être envoyé à la base de données.

page config.php

<?php

 require_once "../class/bootstrap.php"; 

$db = App::getDatabase(Session::getInstance());

if(App::getAuth()->confirm($db, $_GET['token'], $_GET['id'])) {
    Session::getInstance()->setFlash('success', "Votre compte a été validé");
    App::redirect('account.php');
} else {
    Session::getInstance()->setFlash('danger', "Ce token n'est plus valide");
    App::redirect('login.php');
}

je n ai pas le message success apres avoir valider l inscription

page account.php

require_once "../class/bootstrap.php"; 
  var_dump('confirm'); die;
$auth = App::getAuth()->restrict();

require '../includes/haut_page.php';?>     

<h1> Bonjour <? = $_SESSION['auth']->prenom; ?> </h1>
 <div id="contenu">
  <div id="menu_gauche"><h3><center>Mon compte</center></h3>

        <ul>

         </br>
                <li><a href="">Les cours</a></li>
                </br>
                 <?php if (isset($_SESSION['auth']->restrict['rang_id'('2, 3, 4, 5')])): ?>
                    <li><a href="../jsp1.php">JSP1</a></li>

                        <?php elseif ('2, 3, 4, 5, 6') : ?>
                    <li><a href="../jsp2.php">JSP2</a></li>

                        <?php elseif ('2, 3, 4, 5, 6, 7'): ?>
                    <li><a href="../jsp3.php">JSP3</a></li>

                        <?php elseif ('2, 3, 4, 5, 6, 7, 8'): ?>
                    <li><a href="../jsp4.php">JSP4</a></li>

                        <?php endif; ?>
                </ul>
            <ul>
                <li><a href="">Controle</a></li>
                <li><a href="">Mes notes</a></li>
                <li><a href="">Contacter un encadrent</a></li></br>

                 <li><a href="passw_modif.php">Changer mon mot de passe</a></li>
        </ul>

  </div>
         <div class="news"><h1> News </h1></div>       
    <br>
 <?php include '../includes/bas_page.php'; 

en placant un var_dump('confirm'); die; avant la restriction j ai string(7) "confirm" la je ne vois pas mais ma BDD n ai pas modifier en cliquant sur le lien du mail !!
mail:
confirm.php?id=&token=G43OGZLXmri8TplrAaee9bhYIyReKfZZBsmMmpUVXn0kqMejxDJwif0vfAJG

token en bdd:
G43OGZLXmri8TplrAaee9bhYIyReKfZZBsmMmpUVXn0kqMejxDJwif0vfAJG
a priori le token est identique
En cliquant sur le lien j arrive sur ma page account sans message de success mais j ai le message "acces interdit"

ci dessous la fonction register et confirm

public function register($db, $Nom, $Prenom, $Age, $mail, $Password){
        $Password = $this->hashpassword($Password);
        $token = str::random(60);

        $db->query('INSERT INTO Users SET Nom = ?, Prenom = ?, Age = ?, rang_id = 1, mail = ?, Password = ?, confirmation_token = ?', [
            $Nom, 
            $Prenom, 
            $Age, 
            $mail, 
            $Password, 
            $token  
        ]);

        $users_id = $db->lastInsertId();
        $mail = strip_tags($mail);

        $header = "From : ".$mail;
        $sujet = "Confirmation de votre mail";
        $message = "Afin de valider votre compte, merci de cliquer sur ce lien\n\n".$_SERVER['.$_SERVER_NAME']."/sitejsp1/membres/confirm.php?id=".$user_id."&token=".$token;

        mail($mail, $sujet, $message, $header);
 public function confirm($db, $user_id, $token) {
        $user = $db->query('SELECT id FROM users WHERE confirmation_token = ?', [$user_id])->fetch();

        if ($user && $user->confirmation_token == $token) {
          $req = $db->query('UPDATE users SET confirmation_token = NULL, confirmed_at = NOW() WHERE id = ?', [$user_id]);

            $this->session->write('auth', $user);

            return true;
        }

        return false;

merci pour l aide car si on reussi pas a regler ce probleme ca va etre compliqué pour le reste de la construction du site lol

Merci pour ta reponse lartak, je t avoue qu'a force de lire, regarder xxx video sur le php je me suis perdu et embrouillé tous seul le premier code fonctionnais et je suis tombé sur la refactorisation mais tu as raison je vais me reconcentrer sur du php de base histoire de comprendre correctement.