How To Create Login Attempt Limit Form In PHP Using MySQL Database

Hello, Guys today we are going to learn how to limit the number of login attempts using PHP and MySQL. Sometimes you need to add extra protection to a password protected website. This article describes how to restrict access to the login page after three failed login attempts. There are a number of reasons for limiting access. One reason is security. This PHP script uses the visitor’s IP address to store login attempts to the MySQL database and to block login access for 10 minutes after the third failed attempt.

See also Creating multi user role based admin using PHP Mysql and bootstrap

Create Database and Table by SQL query

In first step, we need to create database and table, so here I created webscodex database and admins table with id, name, username, password column and another table name is loginlogs table with id, ipaddress and trytime column . You can simply create “admins” table as following SQL query.

Admins MySQL table Structure:

-- Table structure for table `admins`

CREATE TABLE `admins` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `username` varchar(50) NOT NULL,
  `password` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Loginlogs MySQL table Structure:

-- Table structure for table `loginlogs`

CREATE TABLE `loginlogs` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `IpAddress` varbinary(16) NOT NULL,
  `TryTime` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Login Preview:

How To Create Login Attempt Limit Form In PHP Using MySQL Database

Create Database Configuration file

In this step, we require to create database configuration file, here we will set database name, username and password. So let’s create “config.php” file on your root directory and put bellow code:

config.php

<?php
	/* Database credentials. Assuming you are running MySQL
	server with default setting (user 'root' with no password) */
	define('DB_SERVER', 'localhost');
	define('DB_USERNAME', 'root');
	define('DB_PASSWORD', '');
	define('DB_NAME', 'webscodex');
	 
	/* Attempt to connect to MySQL database */
	$conn = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
	 
	// Check connection
	if($conn === false){
	    die("ERROR: Could not connect. " . $conn->connect_error);
	}
?>

Now create a function for IP address

<?php
// Getting IP Address 
   function getIpAddr(){
      if (!empty($_SERVER['HTTP_CLIENT_IP'])){
         $ipAddr=$_SERVER['HTTP_CLIENT_IP'];
      }elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
         $ipAddr=$_SERVER['HTTP_X_FORWARDED_FOR'];
      }else{
         $ipAddr=$_SERVER['REMOTE_ADDR'];
      }
      return $ipAddr;
   }
?>

Create Login HTML Page and PHP Login Attempt limit Code

In this code, we are creating HTML Login page using bootstrap CDN link and code the login logic and store user session time and user name in Session variable for checking user inactivity in another page.

when user enter username and password is correct than redirect to dashboard or profile page.

If the login attempts are 3 (you can customize the login attempts to suit your needs), you will get the error message Many failed login attempts. Please log in within 10 minutes.

If the login attempts do not equal 3, the login information provided by the user will be checked and then compared with the database entry. If the entries match, the user will be redirected to dashboard.php, otherwise the program will check the remaining login attempts. If the remaining login attempts are 0, the error message Too many failed login attempts is displayed. Please sign in after 10 minutes, otherwise Please enter valid login details is displayed. $rem_attm try left ”.

index.php

<?php

  // start session
  session_start();

  // Include database connectivity
    
  include_once('config.php');

  if (isset($_SESSION['ID'])) {
      header("Location:dashboard.php");
      exit();
  }

  if (isset($_POST['submit'])) {

      $errorMsg = "";
      $time = time()-600;
      $ipaddress = getIpAddr();
      
      // Getting total count of hits on the basis of IP
      $query = $conn->query("SELECT count(*) as total_count from loginlogs where TryTime > $time 
      and IpAddress = '$ipaddress'");

      $check_login_row = $query->fetch_assoc();
      $total_count = $check_login_row['total_count'];

      if ($total_count == 3) {
         //Checking if the attempt 3, or youcan set the no of attempt her. For now we taking only 3 fail attempted
         $errorMsg = "To many failed login attempts. Please login after 10 mintus";         
      }else{
         $username = $conn->real_escape_string($_POST['username']);
         $password = $conn->real_escape_string(md5($_POST['password']));  
         
         $query  = "SELECT * FROM admins WHERE username = '$username' AND password ='$password'";
           
         $result = $conn->query($query);

         if($result->num_rows > 0) {
            $row = $result->fetch_assoc();        
            $_SESSION['ID'] = $row['id'];
            $_SESSION['NAME'] = $row['name'];
            $conn->query("DELETE FROM loginlogs WHERE IpAddress ='$ipaddress'");
            header("Location:dashboard.php");
            die();        
         }else{
            $total_count++;
            $rem_attm = 3-$total_count;
            if($rem_attm == 0){
               $errorMsg = "To many failed login attempts. Please login after 10 mintus";
            }else{
               $errorMsg = "Please enter valid login details. $rem_attm attempts remaining";
            }
            $tryTime = time();
            $conn->query("INSERT INTO loginlogs (IpAddress, TryTime) VALUES ('$ipaddress', '$tryTime')");
         }
      }      
  }  
?>

<?php
// Getting IP Address 
   function getIpAddr(){
      if (!empty($_SERVER['HTTP_CLIENT_IP'])){
         $ipAddr=$_SERVER['HTTP_CLIENT_IP'];
      }elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
         $ipAddr=$_SERVER['HTTP_X_FORWARDED_FOR'];
      }else{
         $ipAddr=$_SERVER['REMOTE_ADDR'];
      }
      return $ipAddr;
   }
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <title>How to Create Login Attempt Limit Form in PHP using MySQL Database</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>  
</head>
<body>

<div class="card text-center" style="padding:20px;">
  <h3>How to Create Login Attempt Limit Form in PHP using MySQL Database</h3>
</div><br>

<div class="container">
  <div class="row justify-content-center">
    <div class="col-md-8 col-md-offset-8">
      <?php if (isset($errorMsg)) { ?>
        <div class="alert alert-danger alert-dismissible fade show">
          <button type="button" class="close" data-dismiss="alert">&times;</button>
          <?php echo $errorMsg; ?>
        </div>
      <?php } ?>
    </div>  
  </div>  
  <div class="row justify-content-center">
    <div class="col-md-4 col-md-offset-4">
      <div class="card">
        <div class="card-body">
          <img class="card-img-top" src="img_avatar1.png" style="width:25%;border-radius:50%;margin-left:110px;">
          <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST">
            <div class="form-group">  
              <label for="username">Username</label> 
              <input type="text" class="form-control" name="username" placeholder="Username" required=""></div>
            <div class="form-group">  
              <label for="password">Password</label> 
              <input type="password" class="form-control" name="password" placeholder="Password" required="">
            </div>
            <div class="form-group">
              <input type="submit" name="submit" class="btn btn-primary btn-block" value="Login"> 
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
</body>
</html>

Create Dashboard/Profile after login successful

After successful login, the user will be directed to this page. This page is confirmed with the meeting. If the session is empty, the user will be redirected to the index.php page.

dashboard.php

<?php

session_start();
// Include database connection file
include_once('config.php');

if (!isset($_SESSION['ID'])) {
    header("Location:index.php");
    exit();
}

?>

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>How to Create Login Attempt Limit Form in PHP using MySQL Database</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="container">	
	<div class="card text-center" style="padding:20px; margin-top:50px;">
	  <h3 class="text-primary">How to Create Login Attempt Limit Form in PHP using MySQL Database</h3>
	    <div class="row">
		<div class="col-md-12 text-center" style="padding:50px;">
		    <h3>Welcome <span class="text-success">
		    <?php echo ucwords($_SESSION['NAME']);?>			
		    </span>to the Webs Codex
		    </h3>
		    <p><a href='logout.php'>Logout</a></p>
	        </div>
	    </div>
        </div>
    </div>			
</body>
</html>

Dashboard Preview:

How To Create Login Attempt Limit Form In PHP Using MySQL Database

Create Logout File

This page used to destroy the session.

logout.php

<?php
    session_start();
    session_destroy();
    session_unset($_SESSION['NAME']);
    session_unset($_SESSION['ID']);
    header("Location:index.php");
    die();
?>

You can always support by sharing on social media or recommending my blog to your friends and colleagues.If you have any suggestions / problems about this tutorial, please comment on the form below.😊

Leave a Reply

Your email address will not be published. Required fields are marked *