login script review - pdo
Het ip adres zal ik eens aanpassen. Dat wist ik niet
Het IP adres is inderdaad iets waar ik niet veel gebruik van zie worden gemaakt. Blijkbaar niet een heel erg bekende functie, maar het scheelt veel ruimte in je db en dus ook snelheid.
Ik zal het morgen eens aanpassen en opnieuw posten. Alvast bedankt voor de kritiek!
het IP adres werkt niet. INET_ATON() kan niet omgaan met ipv6 adressen, waar ik schijnbaar dus gebruik van maak (ook al heb ik dat uitgezet). dus het is nog steeds een varchar
ik heb zelf een klein foutje ontdekt in de bruteforce protectie die ik er niet uit krijg: na drie keer foutief inloggen blokkeert dit script het keurig. ook na vijf minuten weer opnieuw in kunnen loggen, prima. maar dan weer een fout wachtwoord (al is dat een dag later) kun je maar 1 keer foutief inloggen, en dan wordt je geblokkeerd. dit zou dus 3 keer moeten zijn. iemand een oplossing?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?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
{
//vul hier je eigen databasegegevens in, verbinding maken met database
$db = new PDO('mysql:host=localhost;dbname=profielwerkstuk', 'root', 'zevenpuntacht');
$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
COUNT(loginFail_id) AS loginAttempts,
(5 - MIN(TIMESTAMPDIFF(MINUTE, dateAndTime, NOW()))) AS minuteRest,
dateAndTime
FROM
loginfail
WHERE
username = :username
HAVING
TIMESTAMPDIFF(MINUTE, dateAndTime, NOW()) < 5";
$triesStmt = $db->prepare($checkTries);
$triesStmt->execute(array(
':username' => $_POST['username']
));
$tries = $triesStmt->fetchAll();
if (count($user) == 1 && $tries[0]['loginAttempts'] < 3)
{
$_SESSION['user'] = array('user_id' => $user[0]['user_id'], 'IP' => $_SERVER['REMOTE_ADDR']);
//pagina waar naartoe nadat er succesvol is ingelogd
header('Location: game.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)
{
if($tries[0]['loginAttempts'] >= 3)
{
$message = 'Please wait ' . $tries[0]['minuteRest'] . ' minutes to login';
}
else
{
$message = 'invalid username/password. Please try again';
}
}
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 PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>login</title>
</head>
<body>
<?php
if (isset($message))
{
echo $message;
}
?>
<fieldset>
<legend>log in</legend>
<form method="post" action="index.php">
<label for="username">username</label><br>
<input type="text" name="username"><br>
<label for="password">password</label><br>
<input type="text" name="password"><br>
<input type="submit" name="login" value="login">
</form>
</fieldset>
</body>
</html>
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
{
//vul hier je eigen databasegegevens in, verbinding maken met database
$db = new PDO('mysql:host=localhost;dbname=profielwerkstuk', 'root', 'zevenpuntacht');
$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
COUNT(loginFail_id) AS loginAttempts,
(5 - MIN(TIMESTAMPDIFF(MINUTE, dateAndTime, NOW()))) AS minuteRest,
dateAndTime
FROM
loginfail
WHERE
username = :username
HAVING
TIMESTAMPDIFF(MINUTE, dateAndTime, NOW()) < 5";
$triesStmt = $db->prepare($checkTries);
$triesStmt->execute(array(
':username' => $_POST['username']
));
$tries = $triesStmt->fetchAll();
if (count($user) == 1 && $tries[0]['loginAttempts'] < 3)
{
$_SESSION['user'] = array('user_id' => $user[0]['user_id'], 'IP' => $_SERVER['REMOTE_ADDR']);
//pagina waar naartoe nadat er succesvol is ingelogd
header('Location: game.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)
{
if($tries[0]['loginAttempts'] >= 3)
{
$message = 'Please wait ' . $tries[0]['minuteRest'] . ' minutes to login';
}
else
{
$message = 'invalid username/password. Please try again';
}
}
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 PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>login</title>
</head>
<body>
<?php
if (isset($message))
{
echo $message;
}
?>
<fieldset>
<legend>log in</legend>
<form method="post" action="index.php">
<label for="username">username</label><br>
<input type="text" name="username"><br>
<label for="password">password</label><br>
<input type="text" name="password"><br>
<input type="submit" name="login" value="login">
</form>
</fieldset>
</body>
</html>
*bump*
toch nog een bumpje. die query gaat mis, en ik krijg het er maar niet uit
Een laatste bump. Ik krijg die query niet werkende, en zou die toch graag werkende zien. Iemand een idee?