Simple Login Security with PHP

Why we need password protected pages

Sometimes we need to restrict who has access to view or work on a web page. This could be for numerous reasons, such as having a "members only" section of a website, or having an administrative section of the website which could be used for editing comments, displaying new pages, processing orders, etc.

Regardless of the reason, there are several things which remain the same when protecting a site's pages.

  1. Nothing is fool proof. - Users tend to be your "weak link" and will cause more security holes by writing down passwords, making the password too simple, etc.
  2. Usernames and passwords are needed as a minimum. - More advanced situations may include limiting the the IP addresses that can access a page, a third piece of information, and/or additional credentials.
  3. Web servers don't "remember" - you've logged in, so you must convince it. - Usually a cookie, or session variable is used to check to see if a user has logged in to a page.
  4. When you think you've properly secured your site, see notice #1. - The key is to make it "good enough", not completely impenetrable.

How we can protect the pages

The simplest way to protect a set of web pages is to follow this simple logic:

  1. Person attempts to access a protected page,
  2. The server checks for a session variable (a variable stored on the server, and is kept for a period of time, while the user is still active on the site) to see if the user is logged in or if they are not logged in,
  3. The web server redirects the user to a login page,
  4. The user supplies login credentials, and either is allowed access at this point, or is denied access.

Simple version in action

<?php
session_start();
$username = 'admin';
$password = 'p@$sw0rd';

if(isset($_POST['loginsubmit'])) {
 	if($_POST['username'] == $username && $_POST['password'] == $password) {
 		$_SESSION['adminLogged'] = true;
 		header('location: admin.php');
 	} else {
 		header('location: login.php');
 	}
} else {
	$self = $_SERVER['PHP_SELF'];
	$self = substr($self, strrpos($self, '/'));
	if(!(isset($_SESSION['adminLogged']) && $_SESSION['adminLogged'] == true)) {
 		if($self != '/login.php') {
 			header('location: login.php');
	 	}
	}
}

The PHP Code Explained

session_start() - This lets PHP know that the session has to start. Without starting a session, you cannot check for, or set, session variables on that page. This command must be on each page you want to use a session variable.

$username = ... - I set up some variables for storing the username and password

if(isset($_POST['loginsubmit'])) - I check to see if a login submit button is pressed. I give the login submit button a special name (loginsubmit), other than submit like normal, so there is no conflict with other submit buttons.

if($_POST['username'] == $username && $_POST['password'] == $password) - This checks to see if the username and password supplied by the user matches the one set up in the previous lines.

&& - This special operator is known as the boolean and. It is checking to see if both the conditions on the left and the right are true. If both are true, then the whole thing is true. If only one is false, then the whole thing is false.

$_SESSION['adminLogged'] = true; - Sets a server session variable equal to true. This can be checked on any other page which has called the session_start command.

$_SERVER['PHP_SELF'] - A server variable that gets the name of the page we are currently on, including the domain name, folders, etc.

substr($self, strrpos($self, '/')) - Removes the domain name, and folders, leaving us with just the name of the file that was called.

f(!(isset($_SESSION['adminLogged']) && $_SESSION['adminLogged'] == true)) - Once again we use the && to check to see if both sides are true. We use the isset() command to see if a session variable called adminLogged' already exists. If it does, then we check to see if the value is set to true. If it doesn't, it will execute the true section of the if statement.

if($self != '/login.php') - If we are not at the login page already, redirect us to the login page.

Other ways of storing usernames and passwords

In this example the username and password were hard coded into the file. While this "works" it means that everyone who has access to the protected section has to use the same user name and password. If someone leaves the organization, then we have to change the username and password for everyone. This method also means that everyone has the same access. If we want to have multiple levels of access, then there is a problem - such as if there was a "registered user" and "admin" access was needed.

A popular way of solving this problem is to use a database. In the database, individual user names are stored, along with their passwords, and possibly their access levels. This allows them to have their own unqiue login, and we can develop their own security level. We can also track who makes what changes if we need to.

The SQL command for something like this might look like:

SELECT access_level FROM users WHERE username='...' AND password='...'

If a record is returned, then the user has entered the correct credentials, if a record is not returned, then the login failed.