Page 1 of 1

Reset Password System Rate Topic: ****- 2 Votes

#1 RamonRobben  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 69
  • View blog
  • Posts: 485
  • Joined: 19-May 14

Posted 20 February 2015 - 07:57 AM

Welcome on my first tutorial on this form.
this tutorial is an improved version of the tutorial: Password Reset System Without Using A Database by Master Jake

So before we begin you need the following things:
1. The PHP email() function must be enabled.
2. You need a database with the email and password of the user because else they cannot reset their password.

Lets Start with the Forms.

this is the forgot_password.php form
<form action="change.php" method="POST">
E-mail Address: <input type="text" name="email" size="20" /> <input type="submit" name="ForgotPassword" value=" Request Reset " />
</form>


this is the reset_password.php form.
<?php echo '
<form action="reset.php" method="POST">
E-mail Address: <input type="text" name="email" size="20" /><br />
New Password: <input type="password" name="password" size="20" /><br />
Confirm Password: <input type="password" name="confirmpassword" size="20" /><br />
<input type="hidden" name="q" value="';
if (isset($_GET["q"])) {
	echo $_GET["q"];
}
	echo '" /><input type="submit" name="ResetPasswordForm" value=" Reset Password " />
</form>';

?>



okay so now we have 2 forms.
the forms are basics html the only differents between the first form and the second form is that the second form echo`s the html
and in the second form you have the code:
if (isset($_GET["q"])) {
	echo $_GET["q"];
}


this code checks if the variable $_POST["q"] is set and if it is then it echo`s the q variable in the valuebox of the hidden input.
so we can later get that q in another form.

So now the PHP code!

Change.php
The full code:

<?php
// Connect to MySQL
    $username = "username"; 
    $password = "password"; 
    $host = "localhost"; 
    $dbname = "databasename"; 
try {
$conn = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password);
}
catch(PDOException $ex) 
    { 
        $msg = "Failed to connect to the database"; 
    } 

// Was the form submitted?
if (isset($_POST["ForgotPassword"])) {
	
	// Harvest submitted e-mail address
	if (filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) {
		$email = $_POST["email"];
		
	}else{
		echo "email is not valid";
		exit;
	}

	// Check to see if a user exists with this e-mail
	$query = $conn->prepare('SELECT email FROM users WHERE email = :email');
	$query->bindParam(':email', $email);
	$query->execute();
	$userExists = $query->fetch(PDO::FETCH_ASSOC);
	$conn = null;
	
	if ($userExists["email"])
	{
		// Create a unique salt. This will never leave PHP unencrypted.
		$salt = "498#2D83B631%3800EBD!801600D*7E3CC13";

		// Create the unique user password reset key
		$password = hash('sha512', $salt.$userExists["email"]);

		// Create a url which we will direct them to reset their password
		$pwrurl = "www.yoursitehere.com/reset_password.php?q=".$password;
		
		// Mail them their key
		$mailbody = "Dear user,\n\nIf this e-mail does not apply to you please ignore it. It appears that you have requested a password reset at our website www.yoursitehere.com\n\nTo reset your password, please click the link below. If you cannot click it, please paste it into your web browser's address bar.\n\n" . $pwrurl . "\n\nThanks,\nThe Administration";
		mail($userExists["email"], "www.yoursitehere.com - Password Reset", $mailbody);
		echo "Your password recovery key has been sent to your e-mail address.";
		
	}
	else
		echo "No user with that e-mail address exists.";
}
?>



So now some explanation:

with this code we are setting the variables so they can be used to make a connection with the Database.
we are using try before we make the connection because then we can see if something goes wrong.
if we made a successful connection with the database then no errors will come up.
but if we fail to make a connection with the database then the variable $msg will be set to an error message wich we can echo out if we needed to.
// Connect to MySQL
    $username = "username"; 
    $password = "password"; 
    $host = "localhost"; 
    $dbname = "databasename"; 
try {
$conn = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password);
}
catch(PDOException $ex) 
    { 
        $msg = "Failed to connect to the database"; 
    } 



So this code checks if the form was entered or if the user just visited the page accidently
if this code is true then it will run, if it is false then it will not run the code.
if (isset($_POST["ForgotPassword"])) {


So the next code will check if the email address is valid.
if the email address is valid then it will continue running the code.
and if the email is not valid then we will stop the code and show the message: Email is not valid
	if (filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) {
		$email = $_POST["email"];
		
	}else{
		echo "email is not valid";
		exit;
	}



This code will check if the email is in the database and set $userExists to the results becuase if we cant find any results the
$userExist['email'] is empty and we cant reset a password from a person that doesnt exsist in our database
and if the email is in the database then it will continue running the code and the database connection will be closed since we dont need it anymore.

also we are binding the parameters to the variables . This helps agains sql injections.
// Check to see if a user exists with this e-mail
	$query = $conn->prepare('SELECT email FROM users WHERE email = :email');
	$query->bindParam(':email', $email);
	$query->execute();
	$userExists = $query->fetch(PDO::FETCH_ASSOC);
	$conn = null;
	
	if ($userExists["email"])



This code will set the password to a hashed value of the mail so it will generate a resetcode by using the hash and the email.
after that we are setting a variable pwrurl to the link where we can change the password from.
after that we show a message that the mail have been send and we mail the information to the user so he can reset his password
$salt = "498#2D83B631%3800EBD!801600D*7E3CC13";

		// Create the unique user password reset key
		$password = hash('sha512', $salt.$userExists["email"]);

		// Create a url which we will direct them to reset their password
		$pwrurl = "www.yoursitehere.com/reset_password.php?q=".$password;
		
		// Mail them their key
		$mailbody = "Dear user,\n\nIf this e-mail does not apply to you please ignore it. It appears that you have requested a password reset at our website www.yoursitehere.com\n\nTo reset your password, please click the link below. If you cannot click it, please paste it into your web browser's address bar.\n\n" . $pwrurl . "\n\nThanks,\nThe Administration";
		mail($userExists["email"], "www.yoursitehere.com - Password Reset", $mailbody);
		echo "Your password recovery key has been sent to your e-mail address.";
		
	}
	else
		echo "No user with that e-mail address exists.";


we are using a sha512 since we dont want that anyone can reset someones password by just going to the page without code and change the password. The Reset code will help to protect us against that.

Reset.php
the full code:

<?php

// Connect to MySQL
    $username = "username"; 
    $password = "password"; 
    $host = "localhost"; 
    $dbname = "databasename"; 
try {
$conn = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password);
//$conn = new PDO('mysql:host=localhost;dbname=test', 'root', '');
}
catch(PDOException $ex) 
    { 
        $msg = "Failed to connect to the database"; 
    } 
    
// Was the form submitted?
if (isset($_POST["ResetPasswordForm"]))
{
	// Gather the post data
	$email = $_POST["email"];
	$password = $_POST["password"];
	$confirmpassword = $_POST["confirmpassword"];
	$hash = $_POST["q"];

	// Use the same salt from the forgot_password.php file
	$salt = "498#2D83B631%3800EBD!801600D*7E3CC13";

	// Generate the reset key
	$resetkey = hash('sha512', $salt.$email);

	// Does the new reset key match the old one?
	if ($resetkey == $hash)
	{
		if ($password == $confirmpassword)
		{
			//has and secure the password
			$password = hash('sha512', $salt.$password);

			// Update the user's password
				$query = $conn->prepare('UPDATE users SET password = :password WHERE email = :email');
				$query->bindParam(':password', $password);
				$query->bindParam(':email', $email);
				$query->execute();
				$conn = null;
			echo "Your password has been successfully reset.";
		}
		else
			echo "Your password's do not match.";
	}
	else
		echo "Your password reset key is invalid.";
}

?>



And now some explanation:

we now know what this code does. and if you dont just read the explanation of Change.php
// Connect to MySQL
    $username = "username"; 
    $password = "password"; 
    $host = "localhost"; 
    $dbname = "databasename"; 
try {
$conn = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password);
//$conn = new PDO('mysql:host=localhost;dbname=test', 'root', '');
}
catch(PDOException $ex) 
    { 
        $msg = "Failed to connect to the database"; 
    } 



So now we are checking if the form was entered and filled in by trying to check if the variable is set.
if it is the code will run and else the code will stop running. if the isset returns a true then we will set our variables to the posted values so
we can use them later in the script.
if (isset($_POST["ResetPasswordForm"]))
{
	// Gather the post data
	$email = $_POST["email"];
	$password = $_POST["password"];
	$confirmpassword = $_POST["confirmpassword"];
	$hash = $_POST["q"];



so here we are trying to regenerate the code so we can check if the code that the user is using is a valid code.
we are doing that by regenerating the key by using the same method as in the Change.php form.
after that it checks if the key is valid and if it is then the code will continue running and if the code is not valid then we will show a error message saying
that the code is not valid.
	$salt = "498#2D83B631%3800EBD!801600D*7E3CC13";

	// Generate the reset key
	$resetkey = hash('sha512', $salt.$email);

	// Does the new reset key match the old one?
	if ($resetkey == $hash)



so here we are checking if the passwords match and if they do then we will secure the passwords by encrypting them.
after that we will run a query so the password of the user gets updated to the new password then the connection will be closed since we dont need it anymore and
we will show the user that the password is changed correctly.
if the passwords dont match or if the reset key is not valid then we will show the error messages of that to the user.

also we are binding the parameters to the variables because this helps agains sql injections.
if ($password == $confirmpassword)
		{
			//has and secure the password
			$password = hash('sha512', $salt.$password);

			// Update the user's password
				$query = $conn->prepare('UPDATE users SET password = :password WHERE email = :email');
				$query->bindParam(':password', $password);
				$query->bindParam(':email', $email);
				$query->execute();
				$conn = null;
			echo "Your password has been successfully reset.";
		}
		else
			echo "Your password's do not match.";
	}
	else
		echo "Your password reset key is invalid.";
}



Yea you now have made your own Password Reset System. Now you only have to make it pretty with some html and css and put it on your website.

Thank you all for reading my tutorial. I hope you liked my tutorial.
and if you have any questions feel free to ask them


if the connection doesnt work or throw errors on you try this:

// Connect to MySQL
    $username = "username";
    $password = "password";
    $host = "localhost";
    $dbname = "databasename";
try {
$conn = new PDO("mysql:host=".$dbhost.";dbname=".$dbname.";charset=utf8", $username, $password);
}
catch(PDOException $ex)
    {
        $msg = "Failed to connect to the database";
    }

\

EDIT IMPORTANT!!
i will update this tutorial ASAP to work perfectly fine with my other tutorials and scripts as well!

This post has been edited by RamonRobben: 24 February 2015 - 08:06 AM


Is This A Good Question/Topic? 3
  • +

Replies To: Reset Password System

#2 Christopher.Burkhouse  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 20
  • Joined: 03-March 15

Posted 04 March 2015 - 10:42 PM

My only concern is, if I'm reading this correctly, it seems like the password reset URL/code is always the same and never expires. Essentially if I go onto a friend's laptop and rip the URL from their history, I could reset their password for them (deviously of course) at a much later time. Of course there are so many ways to give them their code! From temp one-time passwords, temp one-time reset codes (my favorite), and so on, this is an interesting way about it.

-Chris
Was This Post Helpful? 0
  • +
  • -

#3 RamonRobben  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 69
  • View blog
  • Posts: 485
  • Joined: 19-May 14

Posted 05 March 2015 - 09:15 AM

View PostChristopher.Burkhouse, on 04 March 2015 - 10:42 PM, said:

My only concern is, if I'm reading this correctly, it seems like the password reset URL/code is always the same and never expires. Essentially if I go onto a friend's laptop and rip the URL from their history, I could reset their password for them (deviously of course) at a much later time. Of course there are so many ways to give them their code! From temp one-time passwords, temp one-time reset codes (my favorite), and so on, this is an interesting way about it.

-Chris


this is just how the system works, if you want you could add some features in it like what you said because this isnt a Advanced Secured Reset Password System :)
Was This Post Helpful? 1
  • +
  • -

#4 AshleySmith  Icon User is offline

  • D.I.C Head

Reputation: -1
  • View blog
  • Posts: 53
  • Joined: 28-August 15

Posted 28 August 2015 - 07:05 AM

This code is just what I'm looking for, thanks. I've got to figure out how to implement it all though as I'm using Object Oriented PHP with classes and pages split and I'm a true newbie so help very much appreciated if possible(?) working through this.

Can someone kindly reply to add the feature to randomise the salt or expire it at end of session please, or expand on the advanced features to better secure.

And as this is my first post, what's the best practice to actually have someone kindly help implement this code alongside me for my website? That would be much appreciated!

Thanks again!!! :)/>

This post has been edited by andrewsw: 28 August 2015 - 07:08 AM
Reason for edit:: Removed unrelated quote, just press the REPLY button

Was This Post Helpful? 0
  • +
  • -

#5 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 11617
  • View blog
  • Posts: 45,791
  • Joined: 12-June 08

Posted 28 August 2015 - 07:25 AM

Perhaps you need to take a step back and bring yourself up to speed on PHP before trying to wedge this into where ever. You also may get enough experience to fill in the advanced parts yourself!
Was This Post Helpful? 0
  • +
  • -

#6 AshleySmith  Icon User is offline

  • D.I.C Head

Reputation: -1
  • View blog
  • Posts: 53
  • Joined: 28-August 15

Posted 28 August 2015 - 08:56 AM

View Postmodi123_1, on 28 August 2015 - 07:25 AM, said:

Perhaps you need to take a step back and bring yourself up to speed on PHP before trying to wedge this into where ever. You also may get enough experience to fill in the advanced parts yourself!


Thanks! Agreed but not currently on my agenda, hence support request please. I've everything else pretty much done though through tutorial videos and understand the basics, so I guess it's just organisation of this for my site and referencing the pages, and too the additional security requirement as that's beyond my understanding.
Was This Post Helpful? 0
  • +
  • -

#7 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 11617
  • View blog
  • Posts: 45,791
  • Joined: 12-June 08

Posted 28 August 2015 - 09:16 AM

Mkay. Well, to be clear - the tutorials are provided 'as is' and the author, or other volunteers, are not really on a "support request" based system. If you want something more timely or looking for a tutor the 'post a job' and 'volunteer' sections are a nice place to start.
Was This Post Helpful? 0
  • +
  • -

#8 AshleySmith  Icon User is offline

  • D.I.C Head

Reputation: -1
  • View blog
  • Posts: 53
  • Joined: 28-August 15

Posted 28 August 2015 - 09:18 AM

View Postmodi123_1, on 28 August 2015 - 09:16 AM, said:

Mkay. Well, to be clear - the tutorials are provided 'as is' and the author, or other volunteers, are not really on a "support request" based system. If you want something more timely or looking for a tutor the 'post a job' and 'volunteer' sections are a nice place to start.


Ok, I'll see how far I get over the weekend with this. Maybe I can figure it out. Sorry for adding to the thread, I didn't realise I couldn't edit my posts ro would have updated... :)
Was This Post Helpful? 0
  • +
  • -

#9 AshleySmith  Icon User is offline

  • D.I.C Head

Reputation: -1
  • View blog
  • Posts: 53
  • Joined: 28-August 15

Posted 30 August 2015 - 02:51 PM

Hi,

Having issues with the Change.php page. When clicking the Reset Request button on my forgot_password.php page, it's just sending me to the change.php page and displaying my default error page. So, it doesn't look like it's connecting to my database and running through the functions to check e-mail etc...

Can anyone kindly help?
Was This Post Helpful? 0
  • +
  • -

#10 benanamen  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 85
  • Joined: 28-March 15

Posted 13 November 2015 - 08:10 PM

This code is insecure. Nobody should be using it.

Hashes should be generated using mcrypt_create_iv or openssl-random-pseudo-bytes.

You need to use password_hash and password_verify

This post has been edited by benanamen: 13 November 2015 - 08:13 PM

Was This Post Helpful? 0
  • +
  • -

#11 RamonRobben  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 69
  • View blog
  • Posts: 485
  • Joined: 19-May 14

Posted 14 November 2015 - 05:10 AM

View Postbenanamen, on 13 November 2015 - 08:10 PM, said:

This code is insecure. Nobody should be using it.
Hashes should be generated using mcrypt_create_iv or openssl-random-pseudo-bytes.
You need to use password_hash and password_verify


As i already mentioned this tutorial is only to show how the system works. its not an Advanced secured password reset tutorial.

This post has been edited by RamonRobben: 14 November 2015 - 05:23 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1