Forgot Password Implementation

Hi Experts,

can anyone please tell me where can i implement forgot password functionality

for my YII application. do i need to create any new Controller for it??

(OR)

do i need to implement it in SiteController or components/UserIdentity??

what will be best practice in implementing this forgot password functionality??

any useful links on coding as well please??

Thanks in advance…

I tend to have a User or Member controller for this sort of thing. I also implement it with two actions:

  • request_password_reset -

Requests the user’s email address and a captcha code. A VerificationCode model generates a unique code (say 20 chars). Then send an email to the user with a link to the reset_password action and the user ID, verification code record ID and the code itself as query parameters.

  • reset_password -

Checks that the user ID and the ID and code of the verification code record match the database and prompts the user to enter and reenter their new password.

I have a VerificationCode model for the purposes of generating these codes and deactivating them once they’ve been used.

Here’s an example of the sort of URL that’s generated:




http://direct.local/user/reset_password?userid=1&verifid=1&verifcode=mUmb1g4JRyjGju5bFuYD



thanks alot keith. so do we have to store verifid and verifcode in uses table or do we need to maintain any other table to handle this kind of stuff

or

is there any other way to it??

Many Thanks

I use a separate table called VerificationCode, which allows you to generate codes for different purposes, such as email verification at registration and password reset requests.

The VerificationCode model takes care of generating new records with associated expiry times, and then verifying and deactivating the codes.

The schema I use is:




CREATE TABLE `VerificationCode` (

  `Id` int(11) NOT NULL AUTO_INCREMENT,

  `ForeignTableId` varchar(20) COLLATE utf8_unicode_ci NOT NULL,

  `Type` enum('account_activation','password_reset') COLLATE utf8_unicode_ci NOT NULL,

  `UserId` int(11) NOT NULL,

  `VerificationCode` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,

  `Created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

  `Expires` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

  `Active` tinyint(1) NOT NULL DEFAULT '1',

  PRIMARY KEY (`Id`),

  KEY `ForeignTableId` (`ForeignTableId`,`Type`,`UserId`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;



There are lots of ways to handle this sort of functionality though, so use whatever works best for your app. I think it’s fairly common to have a verification code column in the user table and just use that.

Great!! thanks keith…

can you send the verification logic if possible pls???

Thanks a ton :)

I use this static method to verify the code:




	public static function checkCode($type, $verificationId, $verificationCode, $foreignTableId = null, $userId = null)

	{

		$record = VerificationCode::model()->findByPk($verificationId);


		if ($record === null)

			throw new Exception('Verification record not found.');


		if ($type !== $record->Type)

			throw new Exception('Invalid credentials.');


		if ($verificationCode !== $record->VerificationCode)

			throw new Exception('Invalid credentials.');


		if ($userId !== null && $userId !== $record->UserId)

			throw new Exception('Invalid credentials.');


		if ($foreignTableId !== null && $foreignTableId !== $record->ForeignTableId)

			throw new Exception('Invalid credentials.');


		if (!$record->Active || $record->expired)

			throw new Exception('This verification code has expired. Please request a new one.');

	}



I’ll leave you to figure out the rest ;)

cheers keith… thanks alot :) that helps me much

Hi guys, first of all, thank you a lot for this discussion. But I still have a question that how can we make a record of VerificationCode table to be deactive when the expired_date < current_date ? Is it possible for check it inside Mysql (when the expired_date is <= current_date, automatically change the active field) ?