forgot password function in cakephp 2.0

user picture user · Nov 18, 2013 · Viewed 8.3k times · Source

im very new in programming and php..I'm looking to create a simple Forgot Password system using CakePHP where a user will type in their username/email and then receive an email with a link they can click to create a new password.

I've Googled around but not found anything :/

does anyone can help me or give me the link to easy tutorial in cakephp for forgot or reset password??

Answer

Aryan picture Aryan · Nov 19, 2013

Update

Add resetkey field in usertable.

in UserModel create beforeSave action and add this line in that action

public function beforeSave($options = array()) {
            parent::beforeSave($options = array());
            if (isset($this->data['User']['password'])) {
                $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
            }
            $this->data['User']['resetkey'] = Security::hash(mt_rand(),'md5',true);
            return true;
        }

When user apply for forgot passowrd, send this resetkey to his email. SomeController this is hint of forgot action

if($this->request->is('post')) {
    $this->loadModel('User');
    $mail = $this->request->data['User']['mail'];
    $data = $this->User->findByMail($mail);
    $key = $data['User']['resetkey'];
    if(!$data) {
        $message = __('No Such E-mail address registerd with us ');
        $this->Session->setFlash($message,'flash',array('alert'=>'error'));
    } else {
        $key = $data['User']['resetkey'];
        $id = $data['User']['id'];
        $mail = $data['User']['email'];
        $email = new CakeEmail('smtp');
        $email->to($mail);
        $email->from("[email protected]");
        $email->emailFormat('html');
        $email->subject('Password reset instructions from');
        $email->viewVars(array('key'=>$key,'id'=>$id,'rand'=> mt_rand()));
        $email->template('reset');
        if($email->send('reset')) {
        $message = __('Please check your email for reset instructions.');
        $this->Session->setFlash($message,'flash',array('alert'=>'success'));
        } else {
            $message = __('Something went wrong with activation mail. Please try later.');
        $this->Session->setFlash($message,'flash',array('alert'=>'error'));
        }
    }
    $this->redirect('/');
}

Send that reset key to user so when User will change password, Auth will call beforSave save action and will update reset key. so no one can access rest password page using same key.
Email Template

App/View/Emails/reset.ctp

<p>Please click on the link below to reset your password.</p>
<a href="http://<?= $_SERVER['HTTP_HOST']; ?>/reset/<?= $key .'BXX'.$rand.'XXB'. $id ?>/">Click here to reset your account password</a>
<hr />
<p>Alternatively, you can also copy paste the below link into your browser:
</p>
<p>http://<?= $_SERVER['HTTP_HOST']; ?>/reset/<?= $key .'BXX'.$rand.'XXB'. $id ?>/</p>
<p>This email was sent by <?= APPNAME ?>.</p>

You can define APPNAME in App/Config/bootstrap.php By adding following code

define('APPNAME','FooBar');
this is hint of reset action

$this->loadModel('User');
$a = func_get_args();
$keyPair = $a[0];
$key = explode('BXX', $keyPair);
$pair = explode('XXB',$key[1]);
$key = $key[0];
$pair = $pair[1];
$password = $this->request->data['User']['password'];
unset($this->request->data['User']['password']);
$uArr = $this->User->findById($pair);
if($uArr['User']['resetkey'] == $key) {
$this->User->read(null, $pair);
$this->User->set('password', $password);
if($this->User->save()) { 
$message = __('Your password has been reset');
$this->Session->setFlash($message,'flash',array('alert'=>'success')); 
} else {
$message = __('Something has gone wrong. Please try later or <b>sign up again</b>');
$this->Session->setFlash($message,'flash',array('alert'=>'alert')); }
} else {
$message = __('<b>Please check your reset link</b>');
$this->Session->setFlash($message, 'flash', array('alert'=> 'error'));
 }  

In Routs

Router::connect('/reset/*',array('controller'=>'Home','action'=>'reset'));
And your forgot password function is ready