I am currently trying to add 'lockout' functionality to my login system. I've done it by adding a 'blocked' column in my 'users' table in the DB, and adding a table called 'Failed_Logins' which just record the username and time of the failed login.
If a user incorrectly logs in 5 times within an hour, the account is locked for 15 minutes. The locked part works fine, but I am having great difficulty unlocking it after 15 minutes. I want to do some sort of delayed SQL query but nothing I have tried is working.
Inside my login function, I have this:
// check if user is locked out. If they aren't, carry on with login checks
if(isBlocked($conn, $username) == 0){
failed_logins_action($conn, $username, failed_logins_check($conn, $username));
The functions are then as below:
function failed_logins_check($conn, $username) {
require("dbConn.php");
// prepared statement to delete any failed logins older than 1 hour
deletes_old_failed_logins($conn, $username);
// check for failed logins within the hour
$query = $connect -> prepare("SELECT * FROM `Failed_Logins` WHERE `Timestamp` >= date_sub(now(),interval 1 hour) AND `Username` = ?;");
$query -> bind_param("s", $username);
$query->execute();
$query -> store_result(); //Transfers a result set from a prepared statement
// save the number of rows to a variable
$row_count = $query -> num_rows;
return $row_count;
}
and
function failed_logins_action($conn, $username, $amt) {
// for testing purposes
echo $amt;
require("dbConn.php");
$block_user = $conn -> prepare("UPDATE `users`
SET Blocked = ? WHERE Username = ?;");
$block_user -> bind_param("is", $blocked, $username);
if ($amt >= 10) {
// blocked level 2 = perma
$blocked = 2;
} elseif ($amt >= 5) {
// blocked level 1 = temp (15 mins)
$blocked = 1;
} else {
// not blocked
$blocked = 0;
}
$block_user->execute();
$block_user->close();
if ($blocked == 1) {
$unblock_user = $conn -> prepare("CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
DO
UPDATE `users`
SET Blocked = ? WHERE Username = ?;");
$unblock_user -> bind_param("is", 0, $username);
$unblock_user->execute();
//$unblock_user->close();
}
}
It's the final IF statement in the failed_logins_action function which is the problem.
I get the following error when I try to login for the 5th time incorrectly:
Fatal error: Uncaught mysqli_sql_exception: This command is not supported in the prepared statement protocol yet in /home/devpath/public_html/includes/functions.php:382 Stack trace: #0 /home/devpath/public_html/includes/functions.php(382): mysqli->prepare('CREATE EVENT my...') #1
Can somebody please tell me how to delay the unlocking of the account by 15 minutes? In the above code I have it set to 1 minute just for testinf purposes.
I have also tried using PHP's 'sleep' method followed by a regular prepared UPDATE statement, however this did not work. If the user leaves the page during the delay, it just does not activate I think.
I have also tried 'WAITFOR DELAY' but phpmyadmin doesn't seem to allow this command. I am using cPanel phpmyadmin for reference.
I am definitely no expert in PHP or SQL so please be kind lol. Also sorry about some of the dodgy indentation.