Scripts

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

login.php
[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]
neededtables.txt
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
Nog geen reacties.