Really Simple PHP Login / Logout Script Example

Really Simple PHP Login Logout ScriptOne of the first scripts people new to PHP (or any server-side scripting really) create is a login and logout form for their site. Often times beginners get a little confused as to all the parts necessary to creating such a thing. So I thought it would be helpful if I showed a really basic and easy to use PHP login / logout script. The script uses an existing database connection to locate the user attempting to login, verifying their password and granting them credentials to view the rest of a site’s pages. We will attempt to show how the password is looked up and compared, how to setup the HTML form to take in the username and password of the user and how to block access to pages for users who have not yet logged in. So let’s get started!

There are four main parts to a login and logout script in PHP:

  1. The first part is the actual login form which the user fills out and kicks off the login process.
  2. The second is the login mechanism which will take the submitted username and password, find the user’s password in the database and compare their password on file to the one they provided as part of the login.
  3. The third part is then checking a user on each restricted page to see if they have successfully logged in.
  4. Lastly we need a mechanism for destroying that user’s state and basically causing them to go and login again. (aka logout)

Part 1 – Log In Form

Step 1 is about showing a basic login form. You don’t have to create your form exactly like this, but you need a few key elements. You need the form tags which have a method of “post” and an action attribute that either submits to our processing page or, as I like to do it, the current page. You can have the form submit to itself by using $_SERVER[“PHP_SELF”] or by using an empty value. You also need the two input fields which will collect the username and password for the user to login with. In addition to these, you should have a submit button which has a name specified with it. We will call ours “login-submit”. Fitting isn’t it? 😉 This name is important because we will look for it when it comes time to determine if a login request has taken place. I have also included some PHP code that will look for an $error variable and if set will display the contents of the $error.

<!-- This form will post to current page and trigger our PHP script. -->
<form method="post" action="">
	<div class="login-body">
		<?php
			if (isset($error)) {
				echo "<div class='errormsg'>$error</div>";
			}
		?>
		<div class="form-row">
			<label for="emailaddress">Email:</label>
			<input type="text" name="emailaddress" id="emailaddress" placeholder="Email Address" maxlength="100">
		</div>
		<div class="form-row">
			<label for="pass">Password:</label>
			<input type="password" name="pass" id="pass" placeholder="Password" maxlength="100">
		</div>

		<div class="login-button-row">
			<input type="submit" name="login-submit" id="login-submit" value="Login" title="Login now">
		</div>
	</div>
</form>

As you can see from our code above, the form has a method of “post” and an empty action attribute (which will mean it will submit to the same page it is currently on). It also has two fields, “emailaddress” and “pass”. It then has the submit button. The rest of the HTML is up to you to design and style as you see fit.

Part 2 – Login PHP Mechanism

So now we have a form which is submitting a username and password. We need some code that checks to see if some values were posted, use them to find our user in the database and compare the password we have on file to the one they are submitting. If successful, we know they are legit and can setup a session for them. Do keep in mind that this code should always be at the very top of your login.php page and above our form in part 1. We want to make our checks and setup the session first before the rest of the page is seen. If there is an error it will give us a chance to setup our $error variable and display it when we then go to show the form again.

Since the point of this article is talk about logging in and out and not exactly how to establish a database connection, we will assume you have a working database connection made. Here in the example I am using a custom PDO class (be sure to always use mysqli or PDO and never mysql_* style functions).

<?php
	// First start a session. This should be right at the top of your login page.
	session_start();

	// Check to see if this run of the script was caused by our login submit button being clicked.
	if (isset($_POST['login-submit'])) {

		// Also check that our email address and password were passed along. If not, jump
		// down to our error message about providing both pieces of information.
		if (isset($_POST['emailaddress']) && isset($_POST['pass'])) {
			$email = $_POST['emailaddress'];
			$pass = $_POST['pass'];


			// Connect to the database and select the user based on their provided email address.
			// Be sure to retrieve their password and any other information you want to save for the user session.
			$pdo = new Database();
			$pdo->query("SELECT id, email, password, name, level FROM db_users WHERE email = :emailaddr");
			$pdo->bind(':emailaddr', $email);
			$row = $pdo->single();


			// If the user record was found, compare the password on record to the one provided hashed as necessary.
			// If successful, now set up session variables for the user and store a flag to say they are authorized.
			// These values follow the user around the site and will be tested on each page.
			if (($row !== false) && ($pdo->rowCount() > 0)) {
				if ($row['password'] == hash('sha256', $pass)) {

					// is_auth is important here because we will test this to make sure they can view other pages
					// that are needing credentials.
					$_SESSION['is_auth'] = true;
					$_SESSION['user_level'] = $row['level'];
					$_SESSION['user_id'] = $row['id'];
					$_SESSION['name'] = $row['name'];

					// Once the sessions variables have been set, redirect them to the landing page / home page.
					header('location: home.php');
					exit;
				}
				else {
					$error = "Invalid email or password. Please try again.";
				}
			}
			else {
				$error = "Invalid email or password. Please try again.";
			}
		}
		else {
			$error = "Please enter an email and password to login.";
		}
	}
?>

Don’t let this code discourage you. Most of it is inline comments so you know what is going on. We start by first launching our session_start(). We then check if someone submitted something through our login form. If so, the $_POST array is going to contain information about the submission including their username and password. We are going to test these values to make sure they exist and then we are going to use them in a database query which will lookup the user. Notice we just specify the email address in the where clause of our select statement. No need to pass the password too as this is a bit more secure. We just need to find the user in the database.

Once we find them we fetch out their password. We are going to then compare this password (which should be hashed in the database as a security precaution) and compare it to the hashed version of the password the user submitted in the login form. Here we are using a sha256 hash which is secure enough for something like this. If they match, we know we have the right user and they have successfully logged in. At this point we create some session variables. One of these variables is going to be a variable we will check for on each restricted page to know if they are logged in. If this value doesn’t exist, then we know they never came through the login page successfully. We can then safely send them back to login.php to go login. In our example we called this variable “is_auth” and set it to true. Once the session variables are created, we forward the user off to home.php (the landing page you want the user to go to after logging in).

Note: At the time of setting session variables can also be used to send a login timestamp to the database to give a “last login” value. Might be nice if you wish to know when someone has logged in last or restrict their session time.

If the user fails at any point in this process, we are going to be setting up an error message in that $error variable. The rest of the page will then load and that place where we print out $error in the form will trigger showing the user our error message and giving them another shot to login.

Parts 3 & 4 – Checking Authorization On Restricted Pages and Logging Out

At this point all those who have successfully logged in have a session variable which is following them in their session called “is_auth”. At the top of each page we want to restrict, we simply have a little code that will look for this variable. If not found (or has been destroyed) we immediately send the user back to the login page to login. This code goes at the top of each restricted page. Better yet you can put this code into its own file and simply include it at the top of each page using an include() PHP statement (again at the very top of each page).

<?php

session_start();

// Test the session to see if is_auth flag was set (meaning they logged in successfully)
// If test fails, send the user to login.php and prevent rest of page being shown.
if (!isset($_SESSION["is_auth"])) {
	header("location: login.php");
	exit;
}
else if (isset($_REQUEST['logout']) && $_REQUEST['logout'] == "true") {
	// At any time we can logout by sending a "logout" value which will unset the "is_auth" flag.
	// We can also destroy the session if so desired.
	unset($_SESSION['is_auth']);
	session_destroy();

	// After logout, send them back to login.php
	header("location: login.php");
	exit;
}

?>

So again we start our session and check to see if that “is_auth” variable has been set. If not, we immediately forward them off to login.php. If they are logged in, this code is skipped right over and the rest of the page loads as normal.

We have also put in an else if statement here which will listen to any passing of a value called “logout”. If this value is set and its value is “true” we are going to unset our session variable and destroy the session. This is going to make it so that further pages will now no longer see that session variable and redirect them. Effectively logging them out and preventing them from seeing any more restricted pages. Once the session has been destroyed, we send them back to login.php. This logout variable can be passed by a form or through a link or whatever.

Conclusion

So that is all there is to it. Look through the code, read the inline comments and when you feel you have everything put together just remove the verbosity and you will see that this code gets pretty small. I have used this code on many occasions and it has served me well. It should serve as a nice base for further feature expansion. Like including “remember me” functionality, allowing you to set additional information in the user’s session (like we show with a user’s level or the theme options they have set) and allow you to not only check if they are logged in but how they are logged in and if they can actually see various items on the page. All by checking the session variables. I hope this code serves you as well as it has for me and gets you started on the path to creating your own wonderful login and logout mechanisms.

Thanks for reading! 🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks “The Programmers Idea Book” and “Diagnosing the Problem” . He has been a programmer for over 18 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.

  • Dragonbite

    Interesting article! A couple of questions..

    1. Would it be easier to use “password_hash” (http://php.net/manual/en/function.password-hash.php)

    2. Is there an security benefit for having the password returned as opposed to
    $pdo->query(“SELECT id, email, name, level FROM db_users WHERE password=” . $hashed_password . ” and email = :emailaddr”);

    • Thanks for the questions.

      1. I don’t know about easier, but yes password_hash could be a choice and would be on par with what I have done implementation wise. But do remember that password_hash was introduced in 5.5 which many hosts have not yet adopted (lame I know). So my solution would be more widely supported.

      2. I have had a few comments from others stating the exact same thing. The reason I did it this way is two fold… First why run the risk of pushing across a password (even if encrypted) any more than necessary? We should be sensitive about such information. Second, sometimes systems log queries that come in and here would be an instance of passwords (again encrypted) being stored somewhere we may not want them to be. While perhaps it is a bit of paranoia, I rather be on the safe side when handling passwords. The best practice for that is not to throw them around in queries any more than you have to.

      🙂

  • Unkown

    How do you make a password and email known to it?