login + bruteforce protectie PDO
Er zijn hier aardig wat loginscripts te vinden, hier is er nog een. Wat maakt deze speciaal? - gebruik gemaakt van PDO, dus OO geschikt. er is verder niet gebruik gemaakt van objecten, maar dat kun je zelf evt toevoegen. - er zit een bruteforce-protectie in. laatste tijd nogal hot hier, maar tijdens het inloggen bekijkt dit script of er de laatste 5 minuten meer dan 3 keer is proberen in te loggen (instelbaar). zo ja, dan wordt die gebruiker geblokkeerd tot vijf minuten na de eerste poging. de volgende tabellen moeten aanwezig zijn: tabel 'users' met tenminste: - 'user_id' (auto increment) - 'username' - 'password' (minimaal 64 varchar) tabel 'loginfail' met tenminste: - 'username' - 'IP' - 'dateAndTime' (datetime) het wachtwoord is een eevoudige sha256 van de username + password. geen erg sterke beveiliging, maar in een user tabel komt vast meer gegevens voor die je evt hiervoor kunt gebruiken. dat is aan jezelf. het inloggen levert een sessie op met het user_id en het IP adres veel plezier ermee, alle commentaar is welkom! Jeroen
[code]
<?php
ini_set('display_errors', 1); // 0 = uit, 1 = aan
error_reporting(E_ALL);
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
if (isset($_POST['username']) && trim($_POST['username']) != '' &&
isset($_POST['password']) && trim($_POST['password']) != '')
{
try
{
//initialisatie
$maxAttempts = 3; //pogingen binnen aantal minuten (zie volgende)
$attemptsTime = 5; //tijd waarin pogingen gedaan mogen worden (in minuten, wil je dat in seconden e.d. met je de query aanpassen)
//vul hier je eigen databasegegevens in, verbinding maken met database
$db = new PDO('mysql:host=localhost;dbname=dbtable', 'root', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//ophalen gebruikersinformatie, testen of wachtwoord en gebruikersnaam overeenkomen
$checkUsers =
"SELECT
user_id
FROM
users
WHERE
username = :username
AND
password = :password";
$userStmt = $db->prepare($checkUsers);
$userStmt->execute(array(
':username' => $_POST['username'],
':password' => hash('sha256', $_POST['username'] . $_POST['password'])
));
$user = $userStmt->fetchAll();
//ophalen inlogpogingen, alleen laatste vijf minuten
$checkTries =
"SELECT
username
FROM
loginfail
WHERE
DateAndTime >= NOW() - INTERVAL :attemptsTime MINUTE
AND
username = :username
GROUP BY
username, IP
HAVING
(COUNT(username) = :maxAttempts)";
$triesStmt = $db->prepare($checkTries);
$triesStmt->execute(array(
':username' => $_POST['username'],
':attemptsTime' => $attemptsTime,
':maxAttempts' => $maxAttempts
));
$tries = $triesStmt->fetchAll();
if (count($user) == 1 && count($tries) == 0)
{
$_SESSION['user'] = array('user_id' => $user[0]['user_id'], 'IP' => $_SERVER['REMOTE_ADDR']);
//pagina waar naartoe nadat er succesvol is ingelogd
header('Location: index.php');
die;
}
else
{
$insertTry =
"INSERT INTO
loginfail
(username,
IP,
dateAndTime)
VALUES
(:username,
:IP,
NOW())";
$insertStmt = $db->prepare($insertTry);
$insertStmt->execute(array(
':username' => $_POST['username'],
':IP' => $_SERVER['REMOTE_ADDR']
));
if(count($tries) > 0)
{
$message = 'You have too many times tried the wronge username/password. Please wait a few minutes to login';
}
else
{
$message = 'invalid username/password. Please try again';
}
}
}
catch (PDOException $e)
{
$message = $e->getMessage();
}
$db = NULL;
}
else
{
$message = 'please fill in all required information';
}
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>login</title>
</head>
<body>
<?php
if (isset($message))
{
echo $message;
}
?>
<form method="post" action="login.php">
<fieldset>
<legend>log in</legend>
<label for="username">username</label><br>
<input type="text" name="username"><br>
<label for="password">password</label><br>
<input type="password" name="password"><br>
<input type="submit" name="login" value="login">
</fieldset>
</form>
</body>
</html>
[/code]
CREATE TABLE IF NOT EXISTS `loginfail` (
`loginFail_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`IP` varchar(20) NOT NULL,
`dateAndTime` datetime NOT NULL,
PRIMARY KEY (`loginFail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(64) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Reacties
0