Bonjour, je veux ajouter un formulaire dans login pour le mot de passe oublié et puique j'ai pas d'idées meme si c'est mieux que pouvoir modifier le mot de passe apres la connexion j'ai essayé de rajouter un formulaire dans la méthode edit de user mais quand je change le mot de passe il ne se sauvegarde pas voici mon code:
src/controller/usersController.php

function change_password() {
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash('Password has been changed.');
// call $this->redirect() here
} else {
$this->Session->setFlash('Password could not be changed.');
}
} else {
$this->data = $this->User->findById($this->Auth->user('id'));
}
}
template/users/edit/ctp

<h1>Modifier vos informations</h1>
<?php

//debug($user);
echo $this->Form->create($user);
echo $this->Form->input('first_name');
echo $this->Form->input('last_name');
echo $this->Form->input('email');
echo $this->Form->input('current_password');
echo $this->Form->input('password1');
echo $this->Form->input('password2');
echo $this->Form->button(__('Maj'));
echo $this->Form->end();
?>

Model/Table/UsersTable.php

<?
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Auth\DigestAuthenticate;
use Cake\Event\Event;

class UsersTable extends Table
{

public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('first_name', "A first_name is necessary")
->notEmpty('last_name', 'A last_name is necessary')
->notEmpty('email', 'An email is necessary')
->notEmpty('password', 'A password is necessary');

}
public function beforeSave(Event $event)
{
    $entity = $event->data['entity'];

    // Make a password for digest auth.
    $entity->digest_hash = DigestAuthenticate::password(
        $entity->email,
        $entity->plain_password,
        env('SERVER_NAME')
    );
    return true;
    if (isset($this->data[$this->alias]['password1'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password1']);
    }
    return true;

}

public function checkCurrentPassword($data) {
    $this->id = AuthComponent::user('id');
    $password = $this->field('password');
    return(AuthComponent::password($data['current_password']) == $password);
}

}

si vous pouvez m'aider je serai reconnaissante

5 réponses


Bonjour.
Tu fais erreur, une action de mot de passe oublié, ne se fait que lorsque l'utilisateur n'est pas connecté (sinon, comment pourrait'il entrer son mot de passe pour se connecter s'il ne s'en rappelle plus ?).
Donc, pour te donner une idée, tu fais un lien qui mènera l'utilisateur sur une page qui lui demandera de remplir un formulaire en saisissant son adresse email d'inscription, si l'adresse email est trouvé dans la BDD, tu lui envois un email disposant d'un lien qui contiendra un token et son id utilisateur.
L'utilisateur clique sur le lien et tu lui proposes de modifier son mot de passe.
Voilà, je n'ai pas donné les détails mais ça te donne une démarche à suivre.

Au fait, c'est quoi ce mélange de CakePHP versions 2 et 3 ?

/* CakePHP 2 */
$this->Session->setFlash /* CakePHP 2

/* CakePHP 3 */
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Auth\DigestAuthenticate;
use Cake\Event\Event;

class UsersTable extends Table
Houdette
Auteur

@Lartak, Oui le but c'est modifier le mot de passe donc ou bien il se connecte et il le modifie ou bien avant de se connecter il le modifie c'est pour ça j'ai pensé à mot de passe oublié parce que c'est mieux ça permet la modification et en meme temps en cas d'oublie il pourrait réctifier son compte . si vous pouvez détailler un peu plus je serai reconnaissante.
en ce qui concerne le mélange j utilise cakephp 3 et je suis débutante (je suis en stage et c'est la premiee fois ou je developpe un sited web avec ce framework) c'est pour cela je maitrise pas trop la différence entre le 2 et le 3 et je n'ai que internet et ce forum pour avancer .

Un mot de passe oublié, c'est lorsque l'utilisateur n'est pas connecté et pour lui permettre de le modifier, il faut que tu fasse le vérification avec son email d'inscription.
Si tu veux lui permettre de modifier son mot de passe avec un formulaire commun avec la modification de son compte, il te suffit qu'une fois qu'il à cliqué sur le lien dans l'email envoyé, tu vérifies si le lien avec l'id et le token est correct, dans le cas où c'est bon, tu connectes l'utilisateur et le redirige vers la page de modification de son mot de passe.
Bien qu'il est préférable de lui faire changer son mot de passe avant de le connecter, car s'il ne change pas son mot de passe après avoir été connecté et redirigé, il y a le risque qu'il fasse la demande de mot de passe oublié à chaque fois qu'il voudra se connecter par la suite.
C'est pourquoi, il est préférable de dissocier une modification de mot de passe après oubli de celui-ci et un changement normal de celui-ci.

Salut, si je comprends bien tu veux que quand ton utilisateur est connecté il puisse changer son mot de passe et quand il n'est pas co il doit redemander son mot de passe par email? Si c'est ça pour envoyé l'email de récupération de mot de passe, créé un champs "token (Varchar de 150)" et puis dans ton UsersController:

  • Tu appel la table Users ensuite tu fais un find:
    $user = $users->find('all')->where(['email' => $this->request->data('email')])->first();
  • Donc ensuite tu fais comme d'hab if($this->request->is.......) juste après cette ligne tu créé le token:
    $token = hash('sha512', sha1(rand() . uniqid() . time()));
  • Donc après tu dis que $user->token = $token puis tu fais:

                if ($this->Users->save($user)) {
                    // Si la sauvegarde à été faite alors on envois l'email
                    $email = New Email('default');
                    $email->from('email@emailbidon.fr') // ici tu mets l'email que tu veux qu'il soit afficher comme l'envoyeur
                        ->subject(' Réinitialisation du mot de passe')
                        ->to($this->request->data('email'))
                        ->emailFormat('html')  // html ou text
                        ->template('forgot') // le template de l'email
                        ->viewVars(['token' => $token, 'id' => $user['Users']['id']])
                        ->send(); // tu peux aussi créer ton mail ici mais c'est vraiment pratique ^^
                    $this->Flash->success(__("Un email vous a été envoyé avec les instructions pour réinitialiser votre mot de passe"));
                }

    Après je pense que tu peux compléter toi même, puis pour vérifier les informations une fois l'utilisateur sur la page du mot de passe:

    public function password($id, $token){
        // Tu charge la table users et tu récupère l'utilisateur ou l'id correspond à l'id demandé et idem pour le token
        $users = TableRegistry::get('Users');
        $user = $users->find()->where(['id' => $id, 'token' => $token])->first();
    
        if (empty($user)) {
            // Si l'id et/ou le token ne correspondent pas on indique une erreur
            $this->Flash->error('Ce lien ne semble pas bon');
            return $this->redirect(['controller' => 'Articles', 'action' => 'index']);
        }
        // changement tu mot de passe
        if(!empty($this->request->data)) {
            if ($this->request->is(['post', 'put', 'patch'])) {
                $user = $this->Users->patchEntity($user, $this->request->data);
                if ($this->Users->save($user)) {
                    $this->Flash->success("Votre mot de passe a bien été modifié");
                    return $this->redirect(['action' => 'login']);
                }
            }
        }
        $this->set('user', $user);
    }

Pour les vues je pense que tu peux le faire toute seule ^^
En espérant t'avoir aidé.

salut
Noublie pas de hacher le mot de passe. Car cakephp ne le fait par défaut