Posted on: September 28, 2017Updated: November 24, 2017
How to create a cookie based login using PHP?
In this tutorial we are going to make a basic PHP authentication system using sessions to authenticate and also as an attempt counter that will set a cookie and hide the login screen after a few failed attempts. The script will contain ONE hardcoded user login credentials with BCRYPT hashing method as a form of user validation. All will be wrapped up inside a basic IF ELSEIF ELSE condition structure. The tutorial will be done in 3 parts. First will be about creating the authentication system, second about wrapping it up in a condition structure and third about creating a logout file. Note that part 1 and part 2 should both be saved in the same file.
PART 1 - Create authentication system
First we will start a session and create the authentication variables. The $user and $pass variable values are generated from username and password which will be used for this demonstration. So, if you plan to use this script, make sure to change these. You can use the methods here.
<?php
// start a session.
session_start() ;
// Hashed username (SHA-512).
$user = '05ee170f46fd6040a23ebd883d63ef3b2aff55e3d6e01eccbc401088d7de0c153251c27e517ea4ad9bed62980366d1a47ceb312a659e77debda650d870094562' ;
// using BCRYPT with random salt and cost of 11.
$pass = '$2y$11$qRdmhiqM/SnGIpSWOT/K0OSNkGV7FmhWTB6mYp0uD5JyU1yyyxXhq' ;
Next step is to go through the conditions once username field is submitted. It will check if the username and password match and, if so, create a session for the username posted which will redirect to the admin part of the same file. At the same time we will create a session called counter that will count attempts upon authentication failure and set a cookie, if attempts reach certain number. This cookie will be used to redirect to the ban part of the file...both admin and ban part are relevant in PART 2.
// If button login is clicked on, name got from the login form(PART 2), then execute below...
if (isset ($_POST['auth' ])) {
// Username posted is hashed and compared to the above variable. Password uses bcrypt password_verify() function to validate. If authentication is successful, create a user session.
// The session cookie id will be regenerated first to prevent session fixation
if (hash( 'sha512' , ($_POST['username' ])) === $user && password_verify($_POST['password' ], $pass )) {
// Regenerate session id to prevent session fixation
session_regenerate_id() ;
$_SESSION['userlog' ] = $_POST['username' ];
// Store user agent into a session upon authentication
$_SESSION['agent' ] = hash('sha256' , $_SERVER['HTTP_USER_AGENT' ]);
}
// If authentication failed, create a string variable to be displayed below the login form(see PART 2).
if ($_SESSION['userlog' ] !== $_POST['username' ]) {$incorrect = "Your login combination is incorrect! Please try again..." ;}
// If counter session is set, start counting attempts.
if (isset ($_SESSION['counter' ])) {
$_SESSION['counter' ]++;
// When attempts equals 4, set a cookie(banned in our case) for 10 minutes.
if ($_SESSION['counter' ] >= 4 ) {setcookie( 'banned' , 1 , time() +60 *10 ) ;}
}
// Else create and set the counter session to 1, to activate the above code for further attempts.
else {$_SESSION['counter' ] = 1 ;}
}
?>
We could also check for empty $_POST['username'] and display a separate error but it is unnecessary because if the username and password don't match in any case, it will display the incorrect combination error.
PART 2 - Wrap it all up inside the condition structure
This step should be pretty simple. Here, three different parts will be displayed. First part(ADMIN) if user SESSION is created, second(BAN) if the COOKIE is set and third(LOGIN FORM) if none of these previous parts are true. For the first part we will also create a logout button that will redirect to another file(relevant to PART 3).
<!-- 1. User SESSION is successfully created, the admin will be displayed. PHP(7.0) one liner enables to create html code, that responds to the condition, outside of PHP tags. -->
<?php if (isset ($_SESSION['userlog' ]) && $_SESSION['agent' ] === hash('sha256' , $_SERVER['HTTP_USER_AGENT' ])): ?>
<p> Login successful</p>
<!-- Logout button to take action to another file, logout.php in this case. -->
<form action="logout.php" > <input type="submit" name="logout" value="logout" /></form>
<!-- 2. COOKiE was created instead of SESSION, create a string variable to be displayed below. -->
<?php elseif (isset ($_COOKIE['banned' ])): {$banned = 'Maximum attempts exceeded! You are banned for 10 minutes. Try again later...' ;} ?>
<p> <?php echo $banned ;?> </p>
<!-- 3. There was no user SESSION or COOKIE created, yet, so display the login form. -->
<?php else : ?>
<form name="login" action="" method="post" >
<div> Username:<br/><input name="username" type="text" id="username" size="17" ></div>
<div> Password:<br/><input name="password" type="password" id="password" size="17" ></div><br/>
<input type="submit" name="auth" value="login" />
</form>
<!-- Display the authentication failure message(defined in PART 1). -->
<?php echo "<br/>" .$incorrect ; ?>
<!-- End of the condition structure. -->
<?php endif ; ?>
This is pretty basic but you can easily include your own HTML doctype, headers and body elements under each of the conditions.
PART 3 - Create logout.php file
So now all we need is to create a file named logout.php where a new session will be created and destroyed to log out successfuly. After, you may redirect wherever desired.
<?php
// After being redirected, start a new session, again regenerate id(because of the privilege change) and destroy it to successfully log out.
// Redirect to the index.page.
session_start() ;
session_regenerate_id() ;
session_destroy() ;
header("location:index.php" );