To ensure high security and CPNI Compliance of your magento shop, if customer forget password, then required to provide security answer credentials in order to retrieve a new password. This protects customer information and ensures that the original creator of the account will always have a way of getting their account back (if their account had been hacked/stolen).
In this tutorial, I’m going to explain how to add those two fields to the registration page and require them to be provided on the forgot password page – where they the information will be validated.
[For best practice create new module as usual but I am referring core file name here.]
Please open the following files, as we will be working with them:
**/app/code/core/Mage/Customer/controllers/AccountController.php** – This controls all of the functions that we need to edit.
**/app/design/frontend/default/yourtheme/template/forgotpassword.phtml** – This is the template file for the forgot password page.
**/app/design/frontend/default/yourtheme/template/customer/form/register.phtml** – this is the template file for the register page.
**/app/design/frontend/default/yourtheme/template/customer/form/edit.phtml** – this is the template file for the customer dashboard page.
Alright, first things first. We will start by adding the Security Question and Answer fields to the registration page. We will also have to create a new attribute for the two fields.
At the top of register.phtml, add the following code:
<?php
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
// Set up the Security Question Attribute
$AttrCode = 'squestion';
$settings = array (
'position' => 1,
'is_required'=> 1
);
// Set up the Security Answer Attribute
$AttrCode2 = 'sanswer';
$settings2 = array (
'position' => 1,
'is_required'=> 1
);
// Adds both attributes
$setup->addAttribute('1', $AttrCode, $settings);
$setup->addAttribute('1', $AttrCode2, $settings2);
?>
Now, navigate your browser to http://www.yoursite.com/customer/account/create/
By navigating to this page, you have executed the php code we just added to the register.phtml file. Your attributes are now added to database. Please remove or comment out the code we previously added to the register.phtml file (it is no longer needed).
In register.phtml, add the following block of code:
<ul>
<li>
<div class="input-box">
<label for="squestion"><?php echo $this->__('Security Question') ?> <span class="required">*</span></label><br />
<select id="squestion" name="squestion" title="<?php echo $this->__('Security Question') ?>" class="required-entry validate-select">
<option value="What is the name of your dog?">What is the name of your dog?</option>
<option value="What is the name of your favorite teacher?">What is the name of your favorite teacher?</option>
<option value="What is your maiden name?">What is your maiden name?</option>
<option value="In what city were you born?">In what city were you born?</option>
<option value="What is your favorite food?">What is your favorite food?</option>
</select>
</div>
<div class="input-box">
<label for="sanswer"><?php echo $this->__('Security Answer') ?> <span class="required">*</span></label><br />
<input type="text" name="sanswer" id="sanswer" value="<?php echo $this->htmlEscape($this->getFormData()->getSecurityAnswer()) ?>" title="<?php echo $this->__('Security Answer') ?>" class="required-entry input-text" />
</div>
</li>
</ul>
Now, in your forgotpassword.phtml file, find this block of code (around line 25):
<fieldset>
<legend><?php echo $this->__('Retrieve your password here') ?></legend>
<p><?php echo $this->__('Please enter your email below and we will send you a new password.') ?></p>
<ul class="form-list">
<li>
<div class="input-box"><label for="email_address"><?php echo $this->__('Email Address') ?> <span class="required">*</span></label><br/>
<input name="email" alt="email" type="text" id="email_address" class="required-entry validate-email input-text" value="<?php echo $this->htmlEscape($this->getEmailValue()) ?>" /></div></li>
</ul>
<div class="button-set">
<p class="required"><?php echo $this->__('* Required Fields') ?></p>
<a href="<?php echo $this->helper('customer')->getLoginUrl() ?>" class="left">« <?php echo $this->__('Back to Login') ?></a>
<button type="submit" class="form-button right"><span><?php echo $this->__('Submit') ?></span></button>
</div>
</fieldset>
Replace this block of code with this:
<fieldset>
<legend><?php echo $this->__('Retrieve your password here') ?></legend>
<p><?php echo $this->__('Please enter your email below and we will send you a new password.') ?></p>
<ul class="form-list">
<li>
<div class="input-box"><label for="email_address"><?php echo $this->__('Email Address') ?> <span class="required">*</span></label><br/>
<input name="email" alt="email" type="text" id="email_address" class="required-entry validate-email input-text" value="<?php echo $this->htmlEscape($this->getEmailValue()) ?>" /></div>
</li>
<li>
<div class="input-box">
<?
if(strlen($this->htmlEscape($this->getSquestionValue()))>0){
?>
<label for="squestion"><?php echo $this->__('Security Question') ?> <span class="required">*</span></label><br />
<input name="squestion" alt="squestion" type="text" id="squestion" class="required-entry input-text" style="border:0; background:none; font-weight:bold;" value="<?php echo $this->htmlEscape($this->getSquestionValue()) ?>" readonly /></div>
<? } else { ?>
<label for="squestion"><?php echo $this->__('Security Question') ?> <span class="required">*</span></label><br />
<select id="squestion" name="squestion" title="<?php echo $this->__('Security Question') ?>" class="required-entry validate-select">
<option value="What is the name of your dog?">What is the name of your dog?</option>
<option value="What is the name of your favorite teacher?">What is the name of your favorite teacher?</option>
<option value="What is your maiden name?">What is your maiden name?</option>
<option value="In what city were you born?">In what city were you born?</option>
<option value="What is your favorite food?">What is your favorite food?</option>
</select>
</div>
<? } ?>
</li>
<li>
<div class="input-box">
<label for="sanswer"><?php echo $this->__('Security Answer') ?> <span class="required">*</span></label><br />
<input name="sanswer" alt="sanswer" type="text" id="sanswer" class="required-entry input-text" /></div>
</div>
</li>
</ul>
<div class="button-set">
<p class="required"><?php echo $this->__('* Required Fields') ?></p>
<a href="<?php echo $this->helper('customer')->getLoginUrl() ?>" class="left">« <?php echo $this->__('Back to Login') ?></a>
<button type="submit" class="form-button right"><span><?php echo $this->__('Submit') ?></span></button>
</div>
</fieldset>
Alright, your template files are finished. Now we need to edit the AccountController.php code.
Find this block of code:
public function loginAction()
{
if ($this->_getSession()->isLoggedIn()) {
$this->_redirect('*/*/');
return;
}
$this->getResponse()->setHeader('Login-Required', 'true');
$this->loadLayout();
$this->_initLayoutMessages('customer/session');
$this->_initLayoutMessages('catalog/session');
$this->renderLayout();
}
Add this line of code immediately before “$this->getResponse()->setHeader(‘Login-Required’, ‘true’);”
if(!$this->_getSession()->getUsername()){$this->_getSession()->unsForgottenEmail();}
Now, find this block of code within the **loginPostAction** function:
if (!$session->login($login['username'], $login['password'])) {
$session->addError($this->__('Invalid login or password'));
$session->setUsername($login['username']);
}
Replace it with this:
if (!$session->login($login['username'], $login['password'])) {
$session->addError($this->__('Invalid login or password'));
$session->setUsername($login['username']);
$session->setForgottenEmail($login['username']);
}
Now, find this block of code within the **createPostAction** function:
$customer = Mage::getModel('customer/customer')
->setFirstname($this->getRequest()->getPost('firstname'))
->setLastname($this->getRequest()->getPost('lastname'))
->setEmail($this->getRequest()->getPost('email'))
->setPassword($this->getRequest()->getPost('password'))
->setConfirmation($this->getRequest()->getPost('confirmation'))
->setId(null);
Add these lines immediately after the line containing setEmail:
->setSquestion($this->getRequest()->getPost('squestion'))
->setSanswer($this->getRequest()->getPost('sanswer'))
Now we need to edit the forgotPasswordAction() function. So find this block of code:
public function forgotPasswordAction()
{
$this->loadLayout();
$this->getLayout()->getBlock('forgotPassword')->setEmailValue(
$this->_getSession()->getForgottenEmail()
);
$this->_getSession()->unsForgottenEmail();
$this->_initLayoutMessages('customer/session');
$this->renderLayout();
}
And replace it with this:
public function forgotPasswordAction()
{
$this->loadLayout();
$this->getLayout()->getBlock('forgotPassword')->setEmailValue(
$this->_getSession()->getForgottenEmail()
);
if((strlen($this->_getSession()->getForgottenEmail())>0)){
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($this->_getSession()->getForgottenEmail());
//$this->_getSession()->unsForgottenEmail();
if ($customer->getId()) {
$this->getLayout()->getBlock('forgotPassword')->setSquestionValue(
$customer->getSquestion()
);
} else {
$this->_getSession()->addError($this->__('This email address was not found in our records'));
}
}
$this->_initLayoutMessages('customer/session');
$this->renderLayout();
}
Alright, finally we can edit the forgotPasswordPostAction() function. Find this large block of code:
public function forgotPasswordAction()
{
$this->loadLayout();
$this->getLayout()->getBlock('forgotPassword')->setEmailValue(
$this->_getSession()->getForgottenEmail()
);
$this->_getSession()->unsForgottenEmail();
$this->_initLayoutMessages('customer/session');
$this->renderLayout();
}
/**
* Forgot customer password action
*/
public function forgotPasswordPostAction()
{
$email = $this->getRequest()->getPost('email');
if ($email) {
if (!Zend_Validate::is($email, 'EmailAddress')) {
$this->_getSession()->setForgottenEmail($email);
$this->_getSession()->addError($this->__('Invalid email address'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
return;
}
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($email);
if ($customer->getId()) {
try {
$newPassword = $customer->generatePassword();
$customer->changePassword($newPassword, false);
$customer->sendPasswordReminderEmail();
$this->_getSession()->addSuccess($this->__('A new password was sent'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*'));
return;
}
catch (Exception $e){
$this->_getSession()->addError($e->getMessage());
}
}
else {
$this->_getSession()->addError($this->__('This email address was not found in our records'));
$this->_getSession()->setForgottenEmail($email);
}
} else {
$this->_getSession()->addError($this->__('Please enter your email.'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
return;
}
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
}
And replace it with this:
public function forgotPasswordPostAction()
{
$email = $this->getRequest()->getPost('email');
$squestion = $this->getRequest()->getPost('squestion');
$sanswer = $this->getRequest()->getPost('sanswer');
if ($email) {
if (!Zend_Validate::is($email, 'EmailAddress')) {
$this->_getSession()->setForgottenEmail($email);
$this->_getSession()->addError($this->__('Invalid email address'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
return;
}
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($email);
if ($customer->getId()) {
if(($customer->getSquestion()==$squestion)&&($customer->getSanswer()==$sanswer)) {
try {
$newPassword = $customer->generatePassword();
$customer->changePassword($newPassword, false);
$customer->sendPasswordReminderEmail();
$this->_getSession()->addSuccess($this->__('A new password was sent'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*'));
return;
}
catch (Exception $e){
$this->_getSession()->addError($e->getMessage());
}
} else {
$this->_getSession()->addError($this->__('Your security Q&A credentials were incorrect.'));
$this->_getSession()->setForgottenEmail($email);
}
}
else {
$this->_getSession()->addError($this->__('This email address was not found in our records'));
$this->_getSession()->setForgottenEmail($email);
}
} else {
$this->_getSession()->addError($this->__('Please enter your email.'));
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
return;
}
$this->getResponse()->setRedirect(Mage::getUrl('*/*/forgotpassword'));
}
If you navigate to your account login page and the login fails, you will be redirected to the same page telling you that your password/username was incorrect. Now, click on the Forgot Password link that should already be there. You will notice that the username and security question will automatically be filled in for the username you attempted to login to. From here, put in your security answer and your password will be sent to you. If you type in the wrong security answer, you will get a notice saying your security credentials were incorrect.
23.745764
90.385317