How to Code PHP: Login and Forgotten Password Scripts

Here we continue our adventures in how to code PHP. I’m going to go through a couple scripts in this tutorial:

  • A login PHP script
  • A forgot password PHP script

If you haven’t read my previous How to Code PHP articles, you should do that or you will be completely lost. I’m also going to skip all of the html that would normally be included so I can keep this article brief. I use the same HTML on all of these script pages, that I used in the previous PHP Tutorial, so refer to that for the rest of the code.

If you find this article helpful, please click here so more people can find this :)

The How to Code PHP Login Script

Here I’ll explain all of the code needed for a PHP Login script.

<?php

// Start output buffering.

ob_start();

// Initialize a session.

session_start();

require_once(‘./includes/config.inc.php’);

Here I’m opening a stream so that I can easily communicate with the server. For more information on this refer to the previous PHP Tutorial. I’m creating a session and connecting to the database by pulling in the code in the file config.inc.php.

<html>
<head>
<title>New Think Tank</title>
</head>
<body>
<div id=”allcontent”>
<div id=”header”>
</div>
<div id=”sidebar”>
</div>
<div id=”main”>

Here is all of the basic HTML. You obviously will need to fill in more content here. I’m just providing this basic information, so that you can understand how I laid out the overall page.

<?php
if (isset($_POST['submitted'])) { // Check if the form has been submitted.

// Validate the email address.

if (!empty($_POST['email'])) {

$e = escape_data($_POST['email']);

} else {

echo ‘<p><font color=”red” size=”+1″>You forgot to enter your email address!</font></p>’;

$e = FALSE;

}

Here I’m checking if the form has been submitted. If it is I’m checking if the visitor entered an email address with the empty() function. If they did, I store that email address in the variable named $e. If not I tell them that they forgot to enter their email and assign the value of FALSE to the variable $e.

// Validate the password.

if (!empty($_POST['pass'])) {

$p = escape_data($_POST['pass']);

} else {

$p = FALSE;

echo ‘<p><font color=”red” size=”+1″>You forgot to enter your password!</font></p>’;

}

Here I’m performing the same operations I did with the email address.

if ($e && $p) { // If everything’s OK.

// Query the database.

$query = “SELECT user_id, first_name FROM users WHERE (email=’$e’ AND pass=SHA(‘$p’)) AND active IS NULL”;

$result = mysql_query ($query) or trigger_error(“Query: $query\n<br />MySQL Error: ” . mysql_error());

Here I’m making sure they entered a value for both the email and password. If they did I create a query to send to the database. It will get me all of the user_id’s and first_name’s, from the table users, that have an email and password equal to the one entered and an active account. The function SHA() is used in SQL to encrypt the password.

I then assign the results of the query to the variable $result or alert the visitor to any errors that occurred.

if (@mysql_num_rows($result) == 1) { // A match was made.

// Register the values & redirect.

$row = mysql_fetch_array ($result, MYSQL_NUM);

mysql_free_result($result);

mysql_close(); // Close the database connection.

$_SESSION['first_name'] = $row[1];

$_SESSION['user_id'] = $row[0];

The if statement is checking that just one result was provided. We only want one account for each email address set up.

mysql_fetch_array() takes the results of the previous query and stores them in an array named $row.

mysql_free_result() is used to free up the memory being used by the $result variable. This is used to keep everything running as fast as possible. You should always do your best to free up resources on the server when they are no longer needed. The goal here is to turn you into a good and not just an ok PHP coder!

We no longer need the database either so I close the connection with the mysql_close() function.

Then I store the values of the first_name and user_id variables to the session variables, for use later.

// Start defining the URL.

$url = ‘http://’ . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);

// Check for a trailing slash.

if ((substr($url, -1) == ‘/’) OR (substr($url, -1) == ‘\\’) ) {

$url = substr ($url, 0, -1); // Chop off the slash.

}

// Add the page.

$url .= ‘/index.php’;

// ob_end_clean(); // Delete the buffer.

header(“Location: $url”);

// exit(); // Quit the script.

Here I’m defining where I want to redirect the user after everything checks out. $_SERVER[‘HTTP_HOST’] returns the current page the visitor is on and ‘PHP_SELF’, is the current script being run.

I then delete any unneeded slashes from the new url I’m creating. I then add the name of the page I want the visitor to be directed to, being index.php. I close the buffer and quit the script.

} else { // No match was made.

echo ‘<br><br><p><font color=”red” size=”+1″>Either the email address and password entered do not match those on file or you have not yet activated your account.</font></p>’;

}

If I couldn’t locate the visitor in the database or their account hasn’t been activated, I alert them to that fact.

} else { // If everything wasn’t OK.

echo ‘<p><font color=”red” size=”+1″>Please try again.</font></p>’;

}

// mysql_close(); // Close the database connection.

If the variables $e or $p, contained no value, the visitor would be warned to please try again.

} // End of SUBMIT conditional.

?>

<h1>Login</h1>

<p>Your browser must allow cookies in order to log in.</p>

<form action=”login.php” method=”post”>

<fieldset>

<p><b>Email Address:</b> <input type=”text” name=”email” size=”20″ maxlength=”40″ value=”<?php if (isset($_POST['email'])) echo $_POST['email']; ?>” /></p>

<p><b>Password:</b> <input type=”password” name=”pass” size=”20″ maxlength=”20″ /></p>

<div align=”center”><input type=”submit” name=”submit” value=”Login” /></div>

<input type=”hidden” name=”submitted” value=”TRUE” />

</fieldset>

</form>
</div>
</body>

</html>

Here is the rest of the mainly HTML code. It is pretty self explanatory.

How to Code PHP Forgot Password Script

Here I’m going to just give you the specific code needed, if a user forgets their password. You of course need to include the code that connects to the database along with all your HTML, CSS and JavaScript code. All of this code would reside between the body tags of your HTML.

The script asks for an email address. We then check that the email belongs to a valid user. We change that users password and email it back to them.

<?php

if (isset($_POST['submitted'])) { // Handle the form.

if (empty($_POST['email'])) { // Validate the email address.

$uid = FALSE;

echo ‘<p><font color=”red” size=”+1″>You forgot to enter your email address!</font></p>’;

Checks if the form below has been submitted. Then it checks that an email address has been entered with the empty() function. If not we warn the visitor.

} else {

// Check for the existence of that email address.

$query = “SELECT user_id FROM users WHERE email=’”.  escape_data($_POST['email']) . “‘”;

$result = mysql_query ($query) or trigger_error(“Query: $query\n<br />MySQL Error: ” . mysql_error());

Here we are checking that the email address they entered is valid. The query asks for a user_id, form the table users, where the value is equal to the email entered. The escape_data() function cleans up the information entered. For more information on this function, refer to the previous PHP Tutorial.

if (mysql_num_rows($result) == 1) {

// Retrieve the user ID.

list($uid) = mysql_fetch_array ($result, MYSQL_NUM);

If there was a positive response from our query, retrieve the userid. We assign the results using the list function, as if they were an array, but we will only get one result, because we only have one account for each email address.

} else {

echo ‘<p><font color=”red” size=”+1″>The submitted email address does not match those on file!</font></p>’;

$uid = FALSE;

}

}

If the email address wasn’t found with our query, we alert them to that fact.

if ($uid) { // If everything’s OK.

// Create a new, random password.

$p = substr ( md5(uniqid(rand(),1)), 3, 10);

If the query was successful, we create a new 32 digit password for them. For more information on what these functions do, refer to the previous PHP Tutorial. They basically just create a new random password, for temporary use.

// Make the query.

$query = “UPDATE users SET pass=SHA(‘$p’) WHERE user_id=$uid”;

$result = mysql_query ($query) or trigger_error(“Query: $query\n<br />MySQL Error: ” . mysql_error());

This query updates the record in the database, by setting the new password based on the record having the value of the entered email address.

if (mysql_affected_rows() == 1) { // If it ran OK.

// Send an email.

$body = “Your password to log into SITENAME has been temporarily changed to ‘$p’. Please log in using this password and your username. At that time you may change your password to something more familiar.”;

mail ($_POST['email'], ‘Your temporary password.’, $body, ‘From: admin@sitename.com’);

echo ‘<h3>Your password has been changed. You will receive the new, temporary password at the email address with which you registered. Once you have logged in with this password, you may change it by clicking on the “Change Password” link.</h3>’;

Here we check that the update query was successful, with the mysql_affected_rows() function. If it was we create a message to send to the visitor and then mail them their new password.

// mysql_close(); // Close the database connection.

include (‘./includes/footer.html’); // Include the HTML footer.

// exit();

Here we are closing the database connection and the script.

} else { // If it did not run OK.

echo ‘<p><font color=”red” size=”+1″>Your password could not be changed due to a system error. We apologize for any inconvenience.</font></p>’;

}

} else { // Failed the validation test.

echo ‘<p><font color=”red” size=”+1″>Please try again.</font></p>’;

}

Here we are alerting the visitor that we couldn’t change their password, because of either a system error or because they entered the wrong information.

} // End of the main Submit conditional.

?>

<h1>Reset Your Password</h1>

<p>Enter your email address below and your password will be reset.</p>

<form action=”forgot_password.php” method=”post”>

<fieldset>

<p><b>Email Address:</b> <input type=”text” name=”email” size=”20″ maxlength=”40″ value=”<?php if (isset($_POST['email'])) echo $_POST['email']; ?>” /></p>

</fieldset>

<div align=”center”><input type=”submit” name=”submit” value=”Reset My Password” /></div>

<input type=”hidden” name=”submitted” value=”TRUE” />

</form>

</div>

Here is all the HTML, which should be self explanatory.

Well there is my tutorial on how to setup both a login and a forgotten password page with PHP. If you have any questions leave them below.

Till next time…

Think Tank

35 Responses to “How to Code PHP: Login and Forgotten Password Scripts”

  1. rosa says:

    when I reset a user’s password it doesn’t work can I send you my code to see if there’s any error

  2. Kalai says:

    Hai thr, I hv problem with my forgot password. Can u help me to check it?

  3. Randz says:

    Great day guys.. could you help me out with the script that if you want to reset your password..a link would be sent to your email before password would be reset..thanks in advance :)

  4. Ray says:

    thanks, i used the forgot password code but there is error message as follow :
    Fatal error: Call to undefined function escape_data() in /home/fuvuxco/public_html/member_login_-gffdfdsew3245678ueygdtrefscxdxaswertyuijfndgdffe-0-_ueyetd54vdfdre5syd/forgortpw.php on line 35

    please what shoul i do

  5. PalmSpringsAsian says:

    Hi:

    Below is the problem I am having, and I need your help.

    I have been testing my work by filling out the membership registration form using my own Web site.

    I do not know why the password I entered and the one in my database do not match.

    Therefore, when I test my work again by filling out the “forgotten password” form, I got an email showing the different password.

    I have read somewhere about this, and I do not know if it is true and how to fix it.

    An article I have read says that it is because the password field is set as VARCHAR (32) and Mb5 is used.

    I would appreciate any help you may offer.

  6. Pepiño says:

    Thanks for share this article!

  7. Bryan says:

    love your word. will you be producing more?

    • Bryan says:

      i meant work. lol sorry.

    • admin says:

      Thank you very much :) Yes, I’m going to revisit PHP because I think the tutorial could be vastly improved. This was one of my first big tutorials. I need to cover PHP frameworks among many other topics. Feel free to leave requests

      • Bryan says:

        frameworks would be a great idea. More advanced php security for mysql would prob be my only main request. You can never have enough of it. Agian ty so much for your time and sharing your knowledge with us. It is refreshing to finally find someone with the ability to explain things in a down to earth way that makes it easy to understand. I tip my hat to you sir.

  8. Bryan says:

    Would you consider looking at a site for possible security flaws. I am a trying to dive deeper into coding and at least what to see if I’m going in the right path. As you are at this point “A php god” I thought I’d at least ask. It is no problem if you decline. Still love your work. Ty again

    • admin says:

      Thank you for the complement :) I don’t consider myself a PHP God, but I guess I’m ok. I should have covered frameworks in my PHP tutorial and I’ll definitely do that very soon.

      Sadly I can’t run any tests on your site because it may be perceived as an attack that could get me into a lot of trouble. I can however show you the most common ways sites are attacked. Look at my PHP Security tutorial.

      In the PHP security tutorial I show you how all of the following attacks work:
      SQL Injection
      Cross Site Scripting (XSS)
      Malicious Code Encoding
      Session Hijacking
      Session Fixation
      Malicious System Calls
      Buffer Overflows

      I hope that helps – Derek

  9. Bryan says:

    quick question if I may. how do you feel about FILTER_SANITIZE_STRING for validation and security? Do you recommend it? Also PDO connecting to database?

    • admin says:

      Yes, I use FILTER_SANITIZE_STRING now. I also plan to cover PDO in the future. PHP framework tutorials are also in the works. Thank you for the requests :)

  10. tyra says:

    i want to know. admin have a forget password?

  11. Lisa says:

    hi can i ask how do i solve the problem for the function, mail(). It says that it fails to connect to mailserver.

  12. Alex says:

    Hi Derek your work from 3 years ago still doesnt get out of date! You did a great job, writing all these steps and putting in all this effort.
    I have a website with 4 other people. Our password reset system works so far and also the registration process althoug it was developed not with the help of this guidline. The truth is I’m unsatisfied and would like to improve the procedure.
    I would like to change the registration process of our website in a way that you can set your password directly when you create an account, e.g. like Facebook.
    Also I really like that mostly all services offer now that when you reset your password, they send you a mail with a form where you can set your new password directly without this extra step of a temporary code. Also if this doesnt work the Reset-Mail offers you a link with a form where you have to enter and reenter a new password which will be set.
    I really would like to have this way of reseting passwords because its faster and way more convenient. This way you avoid the following step completely: when the person gets the temporary password and doesn’t decide to cange it to someting more memorable right away, next time he will have the same problem again, and reset the password again and use the new temporary password again in case s/he wouldn’t the old temporary password can not be found.
    Thanks in advance!!!
    Alex

    • Derek Banas says:

      Thank you very much :) I’m definitely going to cover PHP again in the future. I’m not particularly happy with this current tutorial now. I much prefer the complete coverage I have been able to achieve with my java tutorials. I get to the requests as soon as possible

  13. Shahbaz Ahmed Bhatti says:

    Very Nice an dgood with detail, thank u so much sir for this tutorial. many thank dear

  14. guru says:

    Really helpful

  15. Kamal says:

    Hello, I really like the you demostrate the scripts ! Good Job.
    Quick question, is there any tutorial for Change the password ? :P

    • Derek Banas says:

      Thank you :) I decided that the easiest thing to do to allow the person to change their password was to say they forgot it. This script could be used as a change the password script as well. I want to update this information very soon when I cover Zend.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Google+