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; ?>