For applications open to the public this method is not advised since anyone could possibly find a valid user email address and spam them with reset passwords.
First create the form
/app/views/users/forgot.ctp
<h2>Forgot Password</h2> <p>Submit your email address and a new password will be emailed to you.</p> <?php echo $form->create('User'); echo $form->input('email'); echo $form->end('Send Password'); ?> <script type="text/javascript"> document.getElementById('UserEmail').focus() </script>Next edit your Users controller at
/app/controllers/users_controller.php
and add the forgot
function.
function forgot(){ if(!empty($this->data)){ $user = $this->User->findByEmail($this->data['User']['email']); if($user){ $user['User']['password'] = $this->__generatePassword(); // Since my users model requires a confirm_password to match the password on update, it is required here // See http://drug-ed.blogspot.com/2011/08/authentication-and-passwords.html $user['User']['confirm_password'] = $user['User']['password']; if ($this->__sendEmail($user['User']['email'], 'New Password', $user['User'], 'newpass')) { if ($this->User->save($user['User'], array('fieldList' => array('password')))) { $this->Session->setFlash(__('An email has been sent with your new password.', true)); $this->redirect(array('action' => 'login')); } else { $this->Session->setFlash(__('The password cound not be saved. Please try again.', true)); } } else { $this->Session->setFlash(__('The email could not be sent. Please try again.', true)); } } else { $this->Session->setFlash('User could not be found.'); } } }My
__sendEmail()
function above is described in detail here.
Here is my __generatePassword
function. Feel free to use it or create your own.
function __generatePassword($length = 8){ $characters = 'abcdefghijklmnpqrstuvwxyz'; $numbers = '123456789'; // No 0 or O so as not to confuse $more = '!@#$%^&_+=-'; $password = ''; $alt = time(); for($i = 0; $i <= $length; $i++){ $alt += rand() % 10; if($alt % 3 == 1){ if($alt % 2 == 1){ $password .= strtoupper($characters[(rand() % strlen($characters))]); } else { $password .= $characters[(rand() % strlen($characters))]; } } elseif($alt % 3 == 2){ $password .= $numbers[(rand() % strlen($numbers))]; } else { $password .= $more[(rand() % strlen($more))]; } } return $password; }Lastly, create your email templates. They can be quite simple.
/app/views/elements/email/text/newpass.ctp
A new password has been requested for the account: <?php echo $data['username'].'.'.PHP_EOL.PHP_EOL; ?> Your new password is: <?php echo $data['password'].PHP_EOL.PHP_EOL; ?> Please use this password to log in, then you can change your password by clicking "Change Password."Since the email is sent before saving, the password isn't hashed yet and will be visible to the user.
Lastly, ensure that you allow access to the
/users/forgot
view by editing /app/app_controller.php
and add 'forgot'
to your $this->Auth->allow()
line.