Wednesday 11 April 2012

Simple PHP Login Script

Login Scripts for PHP are 10 a penny, so I thought I would fling my own up, since there are still a lot of people out there that have problems with these.  I have set the script up to attach to a MySQL datatbase, though I have left out the details as this will be specific to your setup.  It's designed around my standard basic login table so it uses that table name.  If you already have your own table set up you will need to alter the tablename and probably the field names too in the <<<SQL code block to use your own.  Also, if you do not have a column in your login table that identifies if an account is disabled or not you will need to remove the two lines from the <<<SQL code block that read:
AND
uStatus != 0


As the title says, this is just a simple login script, it's about the bare minimum that you should be using for a multi-user portal.

OK, so what we are doing in the script is as follows:  We open up a php Session, that will carry information accross different pages - this is what tells the rest of the pages on the site that the user is logged in.  We identify the user across these pages by assigning values to session variables on successfull login.
We check our login table to make sure the user is registered in the database.  If there are any requests for a signup script I will post one of those also, but this is just the login only. This script looks for the password to be encrypted using an MD5 one way key, this can be changed to not use encryption (Strongly recomend you don't do that) or to use whatever encryption is set using your signup script.  If it finds a match the user name and password then a simple message is displayed, this can be changed to perform a page redirect or any other action you desire. If the script fails to find a match it shows a message and displays the form again for the end user to have another try.
The script uses only mysql_real_escape_string() for an atempt to sanitise form input, but this is applied in a function that you can easily add other checks to if you want.



Free Hosting



so without any further flapping, here's my sample login script :-


<?php
session_start();

mysql_connect('localhost','root','') or die (mysql_error());
//line above will need to be changed to your MySQL server host, user name and password

mysql_select_db('general');
//line above will need to be changed to your database name (this is NOT your table name)

function makeSafe($varToCheck){
$varToCheck = mysql_real_escape_string($varToCheck);
// this can be used to add other checks to the data to increase sanitization, add as many other lines in the same format as above as you desire.

return $varToCheck;
}

$htmlHead = <<<HTML_HEAD
<!DOCTYPE html>
<html lang="en">
<head><title>Login</title></head>
<body>
HTML_HEAD;

$loginForm = <<<LOGIN_FRM
<form action="" method="POST" id="loginForm" name="loginForm">
<label for="name" form="loginForm">User Name : </label>
<input type="text" id="name" name="name" value="" />
<label for="pass" form="loginForm">Password : </label>
<input type="password" id="pass" name="pass" value="" />
<input type="submit" id="subForm" name="subForm" value="Login!" />
</form>
LOGIN_FRM;

if(!isset($_POST['subForm'])){ // check that the form has not (!) been submitted
echo $htmlHead;  //send html header info to the page
echo $loginForm; //send login form to the page
echo "</body></html>"; // tidy up closing the page
}
else{ // if the form has been filled in and submitted
$safeName = makeSafe($_POST['name']);
$safePass = makeSafe($_POST['pass']); 
//$safePass = md5($safePass);
// the above line uses md5 encryption on the password, you can change this to whatever you use in the registration script to encrypt your users password info.

$sql = <<<SQL
SELECT uID, uLevel
FROM login
WHERE
(
uName = '$safeName'
AND
uPass = '$safePass'
AND
uStatus != 0
)
SQL;

$qry = mysql_query($sql) or die(mysql_error()."<br> when trying to run<br>". $sql);
$num = mysql_num_rows($qry);

if($num != false){ //action to perform on success
$row = mysql_fetch_assoc($qry);
$id = $row['uID'];
$level = $row['uLevel'];
$_SESSION['id'] = $id;
$_SESSION['level'] = $level;
$message = "Congratulations {$_POST['name']} Login Successfull";
echo "$htmlHead $message </body></html>";
}
else{ // action to perform on failure
$message = "<span style=\"color:red\">Login Failed with that username and password. Please Try Again.</span><br>";
echo "$htmlHead $message $loginForm </body></html>";
}
}
?>


!!UPDATE!!
In light of PHP7 removing all support for the mysql_ library I have decided to give this script a much needed update to use PDO. Also, I will include a more secure hashing algorithm than the basic MD5 one that is in the code above. Just remember that the password must be hashed using the same method for both the registration and the login or they won't match in the database!
I am going to leave the old code in place purely as a reference - please do not use it in any new scripts that you are writing.

New script using PDO:
<?php
session_start();

$con = new PDO("mysql:host=localhost;dbname=databaseName","userName", "passwrd");
//line above will need to be changed to your MySQL server host, database name (this is NOT your table name), user name and password

function makePass($word=''){
//function to make password hash
  $dbSalt = '$2a$07$'.substr(hash('whirlpool',$word),0,22);
  $dbPass = crypt($word, $dbSalt);
  return substr($dbPass,12);
}

$htmlHead = <<<HTML_HEAD
<!DOCTYPE html>
<html lang="en">
<head><title>Login</title></head>
<body>
HTML_HEAD;

$loginForm = <<<LOGIN_FRM
  <form action="" method="POST" id="loginForm" name="loginForm">
  <label for="name" form="loginForm">User Name : </label>
  <input type="text" id="name" name="name" value="" />
  <label for="pass" form="loginForm">Password : </label>
  <input type="password" id="pass" name="pass" value="" />
  <input type="submit" id="subForm" name="subForm" value="Login!" />
  </form>
LOGIN_FRM;

if(!isset($_POST['subForm'])){
// check that the form has not been submitted
 echo $htmlHead;
 //send html header info to the page
 echo $loginForm;
//send login form to the page
 echo "</body></html>";
// tidy up closing the page
}
 else{
 // if the form has been filled in and submitted
   $name($_POST['name']);
   $pass = makePass($_POST['pass']);
// the above line uses the custom makePass function to create a secure password hash using two-part one-way encryption
   $sql = <<<SQL
   SELECT uID, uLevel
   FROM login
   WHERE (
     uName = :name
     AND
     uPass = :pwd
     AND uStatus != 0
   )
SQL;
 $stmt = $con->prepare($sql);
 $stmt->bindParam(':name', $name, PDO::PARAM_STR);
 $stmt->bindParam(':pwd', $pass, PDO::PARAM_STR);
 $stmt->execute();
 if($stmt->errorInfo()[0] == 00000){
 //if there are no errors returned:
   $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
 }
 else{
 //if there is an error, display it on the screen - !!THIS SHOULD NOT BE USED IN A PRODUCTION SETTING!!
 print_r($stmt->errorInfo()[3]);
 }
 if(count($result) === 1){
 //action to perform on success
 foreach($result as $row){
 $id = $row['uID'];
 $level = $row['uLevel'];
 $_SESSION['id'] = $id; $_SESSION['level'] = $level;
 $message = "Congratulations {$_POST['name']} Login Successfull";
 echo "$htmlHead $message </body></html>";
 }
 }
 else{
// action to perform on failure
 $message = "<span style=\"color:red\">Login Failed with that username and password. Please Try Again.</span><br>";
 echo "$htmlHead $message $loginForm </body></html>";
 }
}
?>