Сброс пароля CakePHP без изменения пароля

#php #cakephp

#php #cakephp

Вопрос:

У меня есть следующая функция в приложении CakePHP 1.3, которая принимает токен и позволяет пользователю изменить свой пароль. Кажется, все работает нормально, за исключением того, что пароль на самом деле не меняется:/ Есть идеи, в чем проблема?

 function admin_changepassword ( $token = null )
    {
        // If has a token or form has been submitted
        if (!empty($token) || !(empty($this->data)))
        {   
            $user = $this->User->find('first',array("MD5(User.email   '".Configure::read('Security.salt')."')"=>$token));

            if (empty($user))
            { 
                $this->redirect(array('admin'=>false,'controller'=>'pages','action'=>'display','home'));
                $this->Session->setFlash('Invalid token'); 
            }
            else
            {
                $this->set('user',$user);
                if (!empty($this->data['User']['password']))
                { 
                    $user['User']['password'] = $this->data['User']['password']; 
                    $this->User->save($this->data); 
                    $this->Session->setFlash('Your password has been changed! Please log in.'); 
                    $this->redirect(array('admin'=>true,'controller' => 'users', 'action' => 'login'));
                }   
            }
        }
        else
        {
            $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
            $this->Session->setFlash('No token');
        }
    }
  

Комментарии:

1. Вы просите свою базу данных хэшировать каждый пароль каждого пользователя для сравнения с этим запросом, что потенциально является чрезвычайно расточительной операцией.

2. Можете ли вы объяснить это подробнее, поскольку я не понимаю, и в этом причина того, что пароль не меняется?

3. Вы запрашиваете WHERE MD5(password...) = 'somestring' . Это означает, что база данных должна выполняться MD5(password...) для каждой строки, чтобы она могла сравнивать ее 'somestring' . Каким вообще должен быть этот токен? Я не думаю, что это ваша проблема. В чем именно ваша проблема? Что он делает?

4. он не изменяет пароль в БД, даже если он показывает flash

5. Вы не устанавливаете id , что обновлять; если я не ошибаюсь. Я считаю, что cake создаст другую запись, если $Model->id она не установлена.

Ответ №1:

Лично я бы сделал что-то подобное; но я предполагаю, что ваш пользователь действительно вошел в систему, используя auth компонент или аналогичный. Непроверено; но логика выглядит так, как будто это должно сработать для меня.

 <?php
function admin_changepassword ($token = NULL) {
    // bail out early if there is no token set, and always set the flash before redirecting.
    if($token==NULL) {
        $this->Session->setFlash('No token');
        $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
    }

    // this is an admin action; the user already be logged in right?
    $this->User->id = $this->Auth->user('id');
    $user_password = $this->User->field('password');

    // does the token match the hashed password, and did they enter a new password?
    if($token==md5($user_password . Configure::read('Security.salt')) amp;amp; !empty($this->data['User']['password'])) {
        $this->User->saveField('password', $this->data['User']['password']);    
        $this->Session->setFlash('Your password has been changed! Please log in.'); 
        $this->redirect(array('admin'=>true,'controller' => 'users', 'action' => 'login'));
    }

    // somethings gone wrong/password was not updated
    $this->Session->setFlash('Your password was not changed.'); 
    $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
}
  

Комментарии:

1. Нет, пользователь не войдет в систему, поскольку он меняет свой пароль, потому что он его забыл! Пользователь является администратором!

2. Но мой код определенно ЗНАЕТ, какой я пользователь, поскольку я показываю сообщение с приветственным адресом электронной почты в представлении, поэтому он знает, что он просто не меняет пароль :/

3. также change password отличается от forgot password . Возможно, вы захотите взглянуть на переименование ваших методов, хотя бы по семантическим соображениям. Изменение подразумевает, что пользователь вошел в систему и хочет изменить свой пароль на что-то новое; следовательно, я предположил, что ваш пользователь вошел в систему.

Ответ №2:

Хорошо, после некоторого тестирования ваша проблема заключается в том, что я изначально предложил в своем комментарии.

Вы не устанавливаете id своего пользователя, поэтому:

$this->User->save($this->data);

это не обновление пароля, это добавление новой строки в вашу базу данных.

Вам необходимо указать идентификатор пользователя для обновления.

 $user = $this->User->find('first',array("MD5(User.email   
                            '".Configure::read('Security.salt')."')"=>$token));

// this line is redundant 
$user['User']['password'] = $this->data['User']['password'];  


$this->User->id = $user['User']['id']; // set user id
$this->User->save($this->data);  //  save it
  

Если вы проверите свою users таблицу, я подозреваю, что вы обнаружите, что есть много пустых записей с «измененным» паролем. Мое тестирование согласуется с руководством по cake.

Ответ №3:

Это старая тема, но она может кому-то помочь

 function changePwd(){
     $this->User->id = $this->data->['User']['id']; //assuming this is set
     //check if the password fields are empty
     //check if the password fields match (password and confirm password one)

    //convert password 
    $this->request->data['User']['password'] = $this->Auth->password($this->data['User']['password'] );

    //saveField worked for me
    if($this->User->saveField('password',$this->request->data['User']['password'])){
        $this->Session->setFlash('Password changed successfully.','flashSuccess');
    }else{ ....
}