CakePHP 3 Сброс пароля

У меня есть следующий код для сброса пароля по ссылке через электронную почту (это прекрасно работает).

В моем контроллере пользователя:

 public function resetpw($token = null) {
$resetpw = $this->Users->findByToken('id');
if ($this->request->is('post')) {
$pw = $this->request->data['password'];
$pwtable = TableRegistry::get('Users');
$newpw = $pwtable->find($resetpw);
$newpw->password = $pw;
if ($pwtable->save($newpw)) {
$this->Flash->success(__('Your password has been successfully updated.'));
return $this->redirect(['action' => 'login']);
}
else {
$this->Flash->error(__('Your password could not be saved. Please, try again.'));
}
}
}

Файл CTP Reset Password:

Сбросить пароль?

<?= $this->Flash->render(); ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your new password.') ?></legend>
<?= $this->Form->input('password', ['label' => 'New Password']) ?>
<?= $this->Form->input('confirmpassword', ['type' => 'password', 'label' => 'Confirm New Password']) ?>
</fieldset>
<?= $this->Form->button(__('Update password')); ?>
<?= $this->Form->end() ?>

У меня также есть следующие правила, касающиеся сравнения двух паролей:

public function validatePasswords($validator)
{
$validator->add('confirmpassword', 'no-misspelling', [
'rule' => ['compareWith', 'password'],
'message' => 'The passwords are not the same.',
]);
return $validator;
}

После ввода двух одинаковых паролей для обоих паролей & Поля comfirmpassword, я получаю следующую ошибку:

Неизвестный метод поиска «SELECT Users.id AS» Users__id, Users.username
КАК Users__username, Users.password AS Users__password, Users.email
КАК Users__email, Users.role AS Users__role, Users.token AS
Users__token ИЗ пользователей Пользователи WHERE Users.token =: c0 «

0

Решение

преамбула

В этом коде есть много странных вещей, поэтому прежде чем продолжить, необходимо прочитать:

Эти разделы должны дать достаточно информации, чтобы иметь структуру кода, которая логически может работать. Это упоминается из-за следующего кода в вопросе:

  • TableRegistry::get('ControllerName') использование — не обязательно
  • Table->findByToken('literal-string') — всегда будет возвращать одно и то же (ничего)
  • $table->find($notAString); — не соответствует API метода find

Обновление поля это просто редактирование

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

// src/Controller/ArticlesController.php

public function edit($id = null)
{
$article = $this->Articles->get($id);
if ($this->request->is(['post', 'put'])) {
$this->Articles->patchEntity($article, $this->request->data);
if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your article.'));
}

$this->set('article', $article);
}

Есть следующие шаги:

  • Найти статью сущности
  • Обновить сущность статьи
  • Сохранить сущность статьи
  • Некоторая обработка ошибок

Эти шаги такие же, как и в сценарии вопроса. Приспосабливая вышеупомянутый код к вопросу, этот код становится:

// src/Controller/UsersController.php

public function edit($token = null)
{
$user = $this->Users->findByToken($token)->first();
if (!$user) {
$this->Flash->success(__('No user with that token found.'));
return $this->redirect('/');
}

if ($this->request->is(['post'])) {
$user->password = $this->request->data['password'];
$user->confirmpassword = $this->request->data['confirmpassword'];
if ($this->Users->save($user)) {
$this->Flash->success(__('Your password has been successfully updated.'));
return $this->redirect(['action' => 'login']);
}
$this->Flash->error(__('Your password could not be saved. Please, try again.'));
}
}

Хеширование пароля?

Это не упоминается в вопросе, но приведенный выше код ожидает, что пользовательский объект хешировать пароль, когда он установлен:

Вы несете ответственность за хеширование паролей до их
сохраняется в базе данных, самый простой способ — использовать функцию установки
в вашей сущности пользователя:

namespace App\Model\Entity;

use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;

class User extends Entity
{

// ...

protected function _setPassword($password)
{
if (strlen($password) > 0) {
return (new DefaultPasswordHasher)->hash($password);
}
}

// ...
}

В противном случае простой текстовый пароль будет сохранен в таблице пользователей, а не в хеш-коде, и вход в систему не будет работать.

2

Другие решения

Других решений пока нет …