CakePHP 3 resetowanie hasła
Funkcje password() i reset() komponentu Auth służą do umożliwienia użytkownikowi resetowania hasła.
Na górze w pliku UsersController.php dodaj.
use Cake\Routing\Router; use Cake\Mailer\Email;Potem dodaj następujące funkcje. Funkcja password() sprawdza czy użytkownik o podanym emailu istnieje. Jeśli tak wysyła emaila na podany adres z linkiem do strony (sendResetEmail()), na której może on zmienić hasło. W urlu przesyłamy ponadto unikalny passkey, którego występowanie będziemy sprawdzać w funkcji reset().
public function password()
{
if ($this->request->is('post')) {
$query = $this->Users->findByEmail($this->request->data['email']);
$user = $query->first();
if (is_null($user)) {
$this->Flash->error('Email address does not exist. Please try again');
} else {
$passkey = uniqid();
$url = Router::Url(['controller' => 'users', 'action' => 'reset'], true) . '/' . $passkey;
$timeout = time() + DAY;
if ($this->Users->updateAll(['passkey' => $passkey, 'timeout' => $timeout], ['id' => $user->id])){
$this->sendResetEmail($url, $user);
$this->redirect(['action' => 'login']);
} else {
$this->Flash->error('Error saving reset passkey/timeout');
}
}
}
}
private function sendResetEmail($url, $user) {
$email = new Email();
$email->template('resetpass');
$email->emailFormat('both');
$email->from('[email protected]');
$email->to($user->email, $user->full_name);
$email->subject('Reset your password');
$email->viewVars(['url' => $url, 'username' => $user->username]);
if ($email->send()) {
$this->Flash->success(__('Check your email for your reset password link'));
} else {
$this->Flash->error(__('Error sending email: ') . $email->smtpError);
}
}
public function reset($passkey = null) {
if ($passkey) {
$query = $this->Users->find('all', ['conditions' => ['passkey' => $passkey, 'timeout >' => time()]]);
$user = $query->first();
if ($user) {
if (!empty($this->request->data)) {
// Clear passkey and timeout
$this->request->data['passkey'] = null;
$this->request->data['timeout'] = null;
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->set(__('Your password has been updated.'));
return $this->redirect(array('action' => 'login'));
} else {
$this->Flash->error(__('The password could not be updated. Please, try again.'));
}
}
} else {
$this->Flash->error('Invalid or expired passkey. Please check your email or try again');
$this->redirect(['action' => 'password']);
}
unset($user->password);
$this->set(compact('user'));
} else {
$this->redirect('/');
}
}
Pozostało nam stworzyć pliki widoków oraz template emaila.
Poniżej formularz, w którym użytkownik wprowadzi swój email.
Plik src/Template/Users/password.ctp:
<?php $this->assign('title', 'Request Password Reset'); ?><div class="users content">
<h3><?php echo __('Forgot Password'); ?></h3>
<?php
echo $this->Form->create();
echo $this->Form->input('email', ['autofocus' => true, 'label' => 'Email address', 'required' => true]);
echo $this->Form->button('Request reset email');
echo $this->Form->end();
?>
</div>
Plik src/Template/Users/reset.ctp:
<?php $this->assign('title', 'Reset Password'); ?>
<div class="users form large-9 medium-8 columns content">
<?php echo $this->Form->create($user) ?>
<fieldset>
<legend><?php echo __('Reset Password') ?>
<?php
echo $this->Form->input('password', ['required' => true, 'autofocus' => true]); ?>
<p class="helper">Passwords must be at least 8 characters and contain at least 1 number, 1 uppercase, 1 lowercase and 1 special character</p>
<?php
echo $this->Form->input('confirm_password', ['type' => 'password', 'required' => true]);
?>
</fieldset>
<?php echo $this->Form->button(__('Submit')); ?>
<?php echo $this->Form->end(); ?>
</div>
Wyświetla on prosty formularz, w którym użytkownik może wprowadzić nowe hasło.
W przypadku funkcji sendResetEmail() musimy utworzyć szablony wiadomości e-mail wyświetlające dwie zmienne, a ponieważ wysyłamy zarówno zwykły tekst, jak i format html,
musimy utworzyć szablon dla każdego z nich.Template emaila, który jest wysyłany do użytkownika.
Plik src/Template/Email/html/resetpass.ctp
<p>Your username is <?php echo $username; ?></p> <p>Click on the link below to Reset Your Password.</p> <p><a href="<?php echo $url; ?>">Click here to Reset Your Password</a></p> <pre>or Visit this Link</pre><br/> <p><a href=""><?php echo $url; ?></a></p>
Plik src/Template/Email/text/resetpass.ctp - szablon dla zwykłego tekstu.
Your username is <?php echo $username; ?> Click on the link below or copy and paste it into your web browser to reset your password: <?php echo $url; ?>
