php script One way to keep a site secure is by requiring a username and password to control how users access the data on the site, which reassures the site owner that he has protections for his site’s offerings from those nefarious elements lurking on the Web. Right? What happens, however, when the users forget the strong password that was required of them? The site will need a good method of resetting the user’s password and getting it to them so they may regain access to the site.

User Information

One can never assume that a user is who he claims to be is simply because he can produce a valid username to the site. When a request for a password reset happens, the site must first confirm the identity of the user who has forgotten his password. This can best be done by collecting some vital information when the user first creates an account on the site. During the account creation process, in addition to the username and password fields that a form will undoubtedly have, the site should ask for some addition personal information that will be used as validation in case of a forgotten password. This information can be such things as the user’s full name and birthday. The site should then provide a field that will allow the user to create a secret question of his choosing along with the valid answer instead of relying on a few generic secret questions. By doing this, it makes it much harder for the account to be broken into, as more research may need to be done by the hacker in order to gain the answer to the secret question.

Validate the User

Once the user has indicated she has forgotten her password and would like it reset, the site must validate the user against the information that was collected upon account creation. The site should present the user with a form to fill out using the personal information stored for the user. The following code (a code snippet of forgot.php) assumes that the account creation form collected a full name and birthday from the user, and created a secret question with its appropriate answer.
<form id="forgot_first" action="forgot.php" method="post">
Please enter in your full name: 
Please enter in your birthdate: 
Month: '.(($i '; ?> Day: '.(($i '; ?> 
Year: '.(($i '; ?> connect_errno) 
die('Database Connection Error: '.$mysqli->connect_errno); 
$sql = sprintf("SELECT secret_question FROM users WHERE user_name = %s", $mysqli->real_escape_string($_SESSION['username'])); 
$result = $mysqli->query($sql); 
if ($result->num_rows) 
{ if ($row = $result->fetch_assoc()) 
{ $question = $row['secret_question']; 
$answer = $row['secret_answer']; } 
$result->free(); } 
$mysqli->close(); ?>
</form>
This code snippet has a session variable named user_name, and it also uses a MySQL database with a table called users that holds all of the personal user information. The next step is to ensure the data passed in the validation form is what is sitting in the database. This can be accomplished this with something like the following code.
if (isset($_POST['validate'])) {

$full_name = (isset($_POST['full_name'])) ? trim($_POST['full_name']) : ';

$answer = (isset($_POST['answer'])) ? trim($_POST['answer']) : ';

$birth_date = $_POST['year'].'-'.$_POST['month'].'-'.$_POST['day'];

require_once('includes/db.php');

@$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);

if ($mysqli->connect_errno)

die('Database Connection Error: '.$mysqli->connect_errno);

$sql = sprintf("SELECT user_name FROM users WHERE full_name = '%s' 
AND birth_date = '%s' AND secret_answer = '%s'",

$mysqli->real_escape_string($full_name), 
$birth_date, $mysqli->real_escape_string($answer));

$result = $mysqli->query($sql);

if ($result->num_rows) {

//...

}

?>
The code validated the data, so it can now be assumed that an actual user is requesting the password reset and not a hacker who gathered all of the pertinent information needed. The next step is presenting a form asking for the email address where the user would like the reset password sent to. Once this data has been collected from the user (in another form posting), the site is ready to create a new, random password and send it to the user.

Generating a Random Password

There are three steps to generating a random password and sending it to the user: the actual generation of the password string, writing that string to the database, and sending the string to the user. The first step involves randomly selecting characters and building a string out of them. The random password length and character composition it is up to the site owner. In the following code, the password will be ten characters in length and contain alphanumeric characters as well as a handful of special characters.
$chars = 'abcdefghijkmnopqrstuvwxyz023456789!@#$';

srand((double)microtime() * 1000000);

$passwd = ';

$chars_length = strlen($chars) - 1;

for ($i = 0; $i < 10; $i++)

$passwd .= substr($chars, (rand() % $chars_length), 1);

?>
In this snippet the $chars string has the characters ‘l’ and ‘1’ omitted from it. These two characters could be confused with one another depending on the font type of the user’s email, which is something that should be avoided when sending a random string to a user. Once the code has created the new password, the code must write it to the database, as shown in this code snippet.
@$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);

if ($mysqli->connect_errno)

die('Database Connection Error: '.$mysqli->connect_errno);

$sql = sprintf("UPDATE users SET passwd = SHA1(%s) WHERE user_name = %s", 
$mysqli->real_escape_string($passwd), 
$mysqli->real_escape_string($_SESSION['username']));

$result = $mysqli->query($sql);

if ($result->num_rows) {

//...

}

?>
Finally, the user should receive an email indicating that the site reset the password and should indicate what that new password is.
$recipient = $_POST['email'];

/* subject */

$subject = 'Password Change Request';

/* message */

$message = ';

$message .= 'Our system has indicated that you have forgotten your 
password and have requested a new one.\r\n\r\n';

$message .= 'Your new password is:\r\n';

$message .= $passwd.'\r\n\r\n';

/* additional header pieces for errors, From, CC's, Bcc's, etc. */

$headers = ';

$headers .= 'From: 

$headers .= 'X-Sender: 

$headers .= 'X-Mailer: PHP\r\n';

$headers .= 'X-Priority: 1\r\n';

$headers .= 'Return-Path: Admin 

/* now it may be mailed */

$did_it_go = @mail($recipient, $subject, $message, $headers);

if ($did_it_go) {

?>

Your new password has been sent to your email address. Check your

email account and login to the site with the password provided.

Remember to go to preferences once you log in and change your

password to something that you will remember but remains secure.

} else {

?>

There was an error while resetting your password. We apologize for any

inconvenience this may have caused.

}

?>

Summary

Giving a user the ability to reset a password when he forgets it is not too difficult a task. The most important thing to remember is making it hard for a hacker to break into an account by forcing the user to post personal information for validation. The rest is mostly trivial coding to check posted data, create the new password, write it to the database, and send that information to the user in an email. With this sort of system, making sure the user has the ability to change his password from within the site is important, because it would be awful for him to have to memorize some random string of letters, numbers, and special characters.