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

Bibliothèques et frameworks PHP Discussion :

Formulaire de modification de mot de passe


Sujet :

Bibliothèques et frameworks PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 33
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut Formulaire de modification de mot de passe
    Bonjour,



    Voilà, je souhaite créé un formulaire de modification de mot de passe à la première connexion. Avant toutes choses, je viens à dire que je me considère comme débutante en CakePHP comme en PHP, mais je suis obligée d'utiliser un framework.

    Je m'explique. La création de compte ne sera pas possible sur mon site, chaque compte sera créé par un administrateur qui entrera un mot de passe provisoire dans la base. Du coup, quand l'utilisateur se connectera la première fois, il sera redirigé vers un formulaire de modification de mot de passe avant d'accéder au site.

    Voici ma table users, dans laquelle j'ai rajouté un champ "first_connect" en booléen. S'il est à 1 cela veut dire qu'il ne s'est pas encore connecté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE IF NOT EXISTS `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `username` varchar(20) NOT NULL,
      `password` varchar(250) NOT NULL,
      `name` varchar(20) NOT NULL,
      `first_name` varchar(20) NOT NULL,
      `email` varchar(250) NOT NULL,
      `status` tinyint(1) NOT NULL,
      `first_connect` tinyint(1) NOT NULL,
      `profil_id` int(11) NOT NULL,
      FOREIGN KEY profil_user_key (profil_id) REFERENCES users (id)
    ) ;
    Voici mon contrôleur, dans lequel j'ai créé une fonction login, qui renvoie à une fonction firstLogin si c'est la première connexion de l'utilisateur.

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    class UsersController extends AppController
    {
        // Fonction permettant l'authentification au site
        public function login()
        {
            if ($this->request->is('post'))
            {
                // Récupère l'identifiant de l'utilisateur
                $user = $this->Auth->identify();
                if($user)
                {
                    $this->Auth->setUser($user);
     
                    // Si l'utilisateur se connecte pour la première fois, il est renvoyé vers le formulaire "first_login"
                    if($user['first_connect'] == 1)
                    {
                        return $this->redirect(['controller' => 'users', 'action' => 'first_login']);
                    }
                    // Sinon il est redirigé vers la page d'accueil
                    else
                    {
                        return $this->redirect($this->Auth->redirectUrl());
                    }               
                }
                $this->Flash->error('Identifiant ou mot de passe incorrect.');
            }
        }
     
        public function firstLogin()
        {        
            $user = $this->Auth->user();
     
                // Vérification de correspondance des deux champs de mot de passe
     
                if($this->data['User']['password'] == $this->data['User']['password2'])
                {  
                    // Enregistrement de modification de mot de passe
                    $user = $this->Users->findById($user['id'])->first();
                    $user->password = $this->data['password'];
     
                    $this->Users->first_connect = 0;
                    //$user = $this->User->save($this->data);
     
                    if ($this->request->is('post'))
                    { 
                        if($this->Users->save($user))
                        {
                            $this->Flash->success(__('Le mot de passe a bien été modifié.'));
                            return $this->redirect(['action' => 'index']);
                        }
                    }
                }
                else
                {
                    $this->Flash->error('Les mots de passe ne correspondent pas.');
                }        
     
        }
     
        // Fonction de déconnexion du site
        public function logout()
        {
            $this->Flash->success('Vous êtes maintenant déconnecté.');
            return $this->redirect($this->Auth->logout());
        }
     
    }

    Et voici ma vue first_login.ctp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <div class="users form large-9 medium-8 columns content">
        <?= $this->Form->create() ?>
        <fieldset>
            <legend><?= __('Modification du mot de passe') ?></legend>
            <?php
                echo $this->Form->input('password', array('label' => 'Mot de passe'));
                echo $this->Form->input('password2', array('type' => 'password', 'label' => 'Confirmer votre mot de passe'));
            ?>
        </fieldset>
        <?= $this->Form->button(__('Submit')) ?>
        <?= $this->Form->end() ?>
    </div>

    Voici mon problème : lorsque je me connecte, je suis bien redirigée vers le formulaire de modification, j'entre mon nouveau mot de passe et la confirmation, lorsque je clique sur le bouton d'enregistrement je suis bien redirigée vers le site et j'ai bien mon message qui me dit que le mot de passe a été modifié. Toutefois, si je me déconnecte et que je tente de me reconnecter, il me dit mot de passe invalide que ce soit avec le nouveau mot de passe, ou l'ancien...

    J'ai remarqué qu'il ne rentrait pas dans mon second if lorsque je fais un die(). Mais alors pourquoi il m'affiche le message Flash lorsque je fais la modification du mot de passe ? o_O

    Je pense que je m'y prends mal pour récupérer les données du formulaire, mais je n'arrive pas à comprendre comment m'y prendre...



    Quelqu'un pourrait-il m'aider ? :honte:



    Ju'

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Par défaut
    Je ne connais pas CakePHP, mais est-tu sûre que le nouveau mot de passe est bien hashé avant d'être stocké dans la base de données? Je ne vois rien qui l'indique dans ton code (mais peut-être est-ce fait en arrière plan?)

  3. #3
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 33
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    Bonjour !

    Oui c'est fait en arrière plan, dans le model User ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class User extends Entity
    {
        protected $_accessible = [
            '*' => true,
            'id' => false,
        ];
     
        protected function _setPassword($value)
        {
            $hasher = new DefaultPasswordHasher();
            return $hasher->hash($value);
        }
    }
    Après une petite vérification, le mot de passe est hashé en sha1.

    EDIT: Ah ! Le nouveau mot de passe... Maintenant que tu le dis, je ne sais pas... Je vais vérifier ça...

  4. #4
    Membre chevronné
    Avatar de Darkaurora
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 382
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Il y a quelque chose d'étrange dans ta méthode firstLogin à la ligne 41 tu écris $this->Users->first_connect = 0;.

    Pour ma part je pense que tu confonds table et entité, ici tu assigne dynamiquement une propriété first_connect à ton objet table "Users".

    Si tu souhaites modifié ton champ first_connect sur la ligne de la base de donnée qui correspond à ton utilisateur connecté (soit tout simplement l'entité) tu devrais plutôt faire ce qui suit:

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $user = $this->Users->findById($user['id'])->first();
     
    $user->password = $this->data['password'];
    $user->first_connect = 0;
    //$user = $this->User->save($this->data);

    Maintenant je pense qu'on peux apporter quelques améliorations à ton code:

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $user = $this->Users->get($user['id']); // Si jamais tu souhaites gérer l'erreur tu devras capturer l'exception qui est levé cf  http://book.cakephp.org/3.0/fr/orm/retrieving-data-and-resultsets.html#Cake\ORM\Table::get
     
     
    // Ensuite utilisons la méthode patchEntity de ta table qui te permet de mettre à jour tout les champs de ton entité d'un seul coup.
    $user = $this->Users->patchEntity($user, ['password' => $this->data['password'], 'first_connect' => 0]);
     
    // N'oublie pas de sauvegarder les informations afin d'éviter de retomber dans le cas d'une première connexion.
    if (!$this->Users->save($user)) {
       $this->Flash->error('Une erreur est survenue lors de la sauvegarde de user.');
    }

    En gros je pense que c'est parce que tu ne modifies pas correctement ton flag de first connexion que ça ne fonctionne pas.

    @Tsilefy CakePHP Hash automatiquement les mots de passe à partir du moment ou on utilise le module d'authentification, les deux mots de passe doivent être normalement déjà hashé dans le controller.

  5. #5
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 33
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    Merci pour ton aide Darkaurora !

    Merci pour le premier code que tu m'as donné. Effectivement, avec ça, le champ first_connect est bien modifié dans la base

    Ensuite, pour le deuxième code que tu m'as donné. Je voulais juste savoir si je dois le mettre dans mon if, ou ailleurs ?
    Parce que là, de la façon que je l'ai fais, ça m'affiche le message d'erreur lors de la sauvegarde ^^'

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public function firstLogin()
        {                
            $this->viewBuilder()->layout('login');
     
            $user = $this->Auth->user();
            echo('Je suis rentrée dans firstLogin()');
     
            if($this->data['User']['password'] == $this->data['User']['password2'])
            {  
                $user = $this->Users->get($user['id']);
                $user->password = $this->data['pass1'];
                $user = $this->Users->patchEntity($user, ['password' => $this->data['password'], 'first_connect' => 0]);
     
                if ($this->request->is('post'))
                { 
                    if (!$this->Users->save($user)) 
                    {
                        $this->Flash->error('Une erreur est survenue lors de la sauvegarde de user.');
                    }
                }
            }
            else
            {
                $this->Flash->error('Les mots de passe ne correspondent pas.');
            }  
        }
    EDIT : je pense que je me suis trompée dans le premier if, c'est pas password et password2, mais pass1 et pass2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Ma vue
     
    <div class="users form large-9 medium-8 columns content">
        <?= $this->Form->create('User', array('type' => 'post')) ?>
        <fieldset>
            <legend><?= __('Modification du mot de passe') ?></legend>
            <?php
                echo $this->Form->input('pass1', array('type' => 'password', 'label' => 'Mot de passe'));
                echo $this->Form->input('pass2', array('type' => 'password', 'label' => 'Confirmer votre mot de passe'));
            ?>
        </fieldset>
        <?= $this->Form->button(__('Submit')) ?>
        <?= $this->Form->end() ?>
    </div>

  6. #6
    Membre chevronné
    Avatar de Darkaurora
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 382
    Billets dans le blog
    1
    Par défaut
    Re,

    $this->Users->save($user) retourne l'entité nouvellement sauvegardé si la sauvegarde réussi OU false si la sauvegarde échoue

    Si tu passes dans le if(!$this->Users->save($user)) {...} c'est que la sauvegarde échoue.

    Tout d'abord lorsque tu fais ça c'est pas complètement faux mais c'est inexact:

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $user->password = $this->data['pass1'];
    $user = $this->Users->patchEntity($user, ['password' => $this->data['password'], 'first_connect' => 0]);

    Ci dessus tu assigne au mot de passe de ton utilisateur le champ $this->data['pass1'] de ton formulaire. Puis tu "patch" ton utilisateur, plus précisément tu le mets à jour avec cette ligne: $user = $this->Users->patchEntity($user, ['password' => $this->data['password'], 'first_connect' => 0]);.
    Donc le mot de passe de ton utilisateur est maintenant égale à $this->data['password'].

    Tout ce que tu dois taper c'est:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $user = $this->Users->patchEntity($user, ['password' => $this->data['pass1'], 'first_connect' => 0]);

    Maintenant voici comment je m'y prendrais pour ta méthode:

    Code php : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    public function firstLogin()
    {
        /**
         * Ici on ne fait une action que si on a reçus des données via POST
         */
        if ($this->request->is('post')) {
            $data = $this->request->data;
            if ($data['pass1'] === $data['pass2']) {
                // On récupère l'entité avec les informations du composant Auth
                $user = $this->Users->newEntity($this->Auth->user());
                // On met à jour l'entité
                $user = $this->Users->patchEntity($user, ['password' => $this->data['password'], 'first_connect' => 0]);
                // On debug l'entité (pour être sûre)
                debug($user);
                // On sauvegarde l'entité
                if (false === $this->Users->save($user)) {
                    $this->Flash->error('Une erreur est survenue lors de la sauvegarde de user.');
                    debug($user->errors()); // Pour vérifier si il y a des erreurs.
                }
            } else {
                $this->Flash->error('Les mots de passe ne correspondent pas.');
            }
        }
     
        /**
         * La méthode render permet de rendre une vue et un layout.
         * Elle automatiquement appelé à la fin d'une action de controller.
         * En lui passant null comme premier paramètre elle va automatiquement
         * rechercher la vue correspondante à ton action.
         * En lui passant 'login' en second paramètre elle va chercher
         * un fichier ctp nommé login dans le répertoire layout de ton application.
         *
         * cf: API http://api.cakephp.org/3.1/source-class-Cake.Controller.Controller.html#574-613
         * cf: DOC http://book.cakephp.org/3.0/fr/controllers.html#rendre-une-view
         */
        $this->render(null, 'login');
    }

  7. #7
    Membre confirmé
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 33
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    J'ai retiré la ligne $user->password = $this->data['pass1']; , mais après avoir posté mon message en fait xD

    Du coup, j'ai mis ton code, et ça me renvoie ceci pour le premier debug (je ne comprends pas pourquoi il n'y a pas le champ password :/ ):

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    object(App\Model\Entity\User) {
     
    	'username' => 'test',
    	'name' => 'test',
    	'first_name' => 'test',
    	'email' => 'test@test.com',
    	'status' => false,
    	'first_connect' => false,
    	'profil_id' => (int) 2,
    	'[new]' => true,
    	'[accessible]' => [
    		'*' => true
    	],
    	'[dirty]' => [
    		'username' => true,
    		'name' => true,
    		'first_name' => true,
    		'email' => true,
    		'status' => true,
    		'first_connect' => true,
    		'profil_id' => true
    	],
    	'[original]' => [
    		'first_connect' => true
    	],
    	'[virtual]' => [],
    	'[errors]' => [
    		'password' => [
    			'_required' => 'This field is required',
    			'_empty' => 'This field cannot be left empty'
    		],
    		'username' => [
    			'_required' => 'This field is required'
    		],
    		'name' => [
    			'_required' => 'This field is required'
    		],
    		'first_name' => [
    			'_required' => 'This field is required'
    		],
    		'email' => [
    			'_required' => 'This field is required'
    		],
    		'status' => [
    			'_required' => 'This field is required'
    		]
    	],
    	'[repository]' => 'Users'
     
    }
    Et ceci pour le second debug :

    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
    18
    19
    20
    21
    [
    	'password' => [
    		'_required' => 'This field is required',
    		'_empty' => 'This field cannot be left empty'
    	],
    	'username' => [
    		'_required' => 'This field is required'
    	],
    	'name' => [
    		'_required' => 'This field is required'
    	],
    	'first_name' => [
    		'_required' => 'This field is required'
    	],
    	'email' => [
    		'_required' => 'This field is required'
    	],
    	'status' => [
    		'_required' => 'This field is required'
    	]
    ]
    Et le mot de passe n'est pas modifié, par contre, l'ancien fonctionne toujours contrairement à avant ^^

Discussions similaires

  1. Formulaire de modification de mot de passe
    Par lizeal dans le forum Langage
    Réponses: 5
    Dernier message: 18/02/2014, 14h33
  2. Réponses: 2
    Dernier message: 02/02/2007, 14h53
  3. Formulaire pour recuperer son mot de passe
    Par Jean73 dans le forum Langage
    Réponses: 4
    Dernier message: 28/03/2006, 12h30
  4. Formulaire protégé par un mot de passe
    Par SpyesX dans le forum Access
    Réponses: 10
    Dernier message: 13/03/2006, 18h02
  5. [LDAP]modification du mot de passe - ligne de commande
    Par sangei dans le forum API standards et tierces
    Réponses: 24
    Dernier message: 01/12/2005, 14h49

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