- VEROUDERD, KAN HEEL GOED DIKKE ONZIN IN STAAN!!! -
Hey
Na hier 2 tutorials gelezen te hebben kon ik het niet laten om mijn tutorial hier te posten. Hier gebruik ik cookies maar sessies kunnen ook!
1: Wat heb je nodig
Een server die PHP en een SQL database heeft.
Een SSL optie.
Een databaseclass
2: De code & uitleg:
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<?php $form = \'<form method=\"post\" action=\"\' . htmlentities($_SERVER[\'PHP_SELF\'], ENT_QUOTES) . \'\"> <table border=\"0\" cellpadding=\"2\"> <tr><td colspan=\"2\" style=\"font-weight:bold; text-align:center\">Inloggen</td></tr> <tr><td style=\"font-weight:bold;\">Gebruikersnaam:</td><td><input type=\"text\" name=\"username\" /></td></tr> <tr><td style=\"font-weight:bold;\">Wachtwoord:</td><td><input type=\"password\" name=\"password\" /></td></tr> <tr><td colspan=\"2\" style=\"margin:0px auto;><input type=\"submit\" value=\"Login\" /> <input type=\"reset\" value=\"Wis invoer\" />/td></tr> </table> </form>\'; // Het formuliertje if($_SERVER[\'REQUEST_METHOD\'] == \'POST\'){ // Hiermee kijken we of het formulier gepost is. sleep(1); // Vertraag het inloggen altijd . $query_getLogintries = $db->query(\"SELECT logintries, tillTimestamp FROM logintries WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); $num_getLogintries = $db->numRows($query_getLogintries); // Kijk of er foutieve inlogpogingen zijn geweest en tel ze. if($num_getLogintries > 0){ // Is er foutief ingelogd? $logintries = $db->fetchAssoc($query_getLogintries); // Haal het aantal loginpogingen op. if($logintries[\'logintries\'] == 3){ // Als er 3 mislukte inlogpogingen izjn if($logintries[\'tillTimestamp\'] < time()){ // Als de 15 minuten voorbij zijn $db->query(\"DELETE FROM logintries WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); // Verwijder de 3 mislukte inlogpogingen omdat de 15 minuten voorbij zijn. }else{ die(\'Je hebt het maximaal aantal loginpogingen overscheren, je mag voor 15 minuten niet meer inloggen.\'); // Sterf met het bericht. } } } if(empty($_POST[\'username\']) || empty($_POST[\'password\'])){ // Even kijken of alles netjes is ingevuld. $error = \'<b style=\"color:#FF0000\">De volgende fouten zijn opgetreden:</b> <br />\'; if(empty($_POST[\'username\'])){ $error .= \'Het veld gebruikersnaam. <br />\'; } if(empty($_POST[\'password\'])){ $error .= \'Het veld wachtwoord <br />\'; } $error . = \'<br /> Probeer het opnieuw: <br /> \' . $form; // Het formulier is niet netjes ingevuld dus we laten de fout(en) zien. }else{ $username = $secure->safeDB($_POST[\'username\']); $password = $secure->hash($_POST[\'password\']); // De maken de gebruikersnaam veilig en het wachtwoord hashen we. $query = $db->query(\"SELECT password FROM members WHERE username = \'\" . $username . \"\'\"); $num = $db->numRows($query); // Haal de rij op met die gebruikersnaam en tel het aantal resultaten. if($num == 0){ // Er zijn 0 rijen dus de gebruikersnaam bestaat niet. $result = \'FAIL:username\'; }else{ $fetch = $db->fetchAssoc($query); // Haal het wachtwoord op om het te vergelijken met de input van de gebruiker. if($fetch[\'password\'] == $password){ // Vergelijk de wachtwoorden met elkaar. $hash = sha1($username.$password.time().rand(1000000, 999999)); /* Hier maken we de hash: 1. Gebruikersnaam 2. Gehashde vorm van het wachtwoord. 3. De timestamp 4. Een random getal van 6 cijfers. */ $db->query(\"INSERT INTO hashes(username, hash, userip) VALUES (\'\" . $username . \"\', \'\" . $hash . \"\', \'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\')\"); // Sla de gebruikersnaam, hash en het IP op in de databaase. setcookie(\'hash\', $hash, time()+3600*24*365); // Plaats een cookie met de naam hash die de inhoud van $hash heeft en een jaar moet bestaan. $result = \'OK:loggedin\'; }else{ $result = \'FAIL:password\'; } } $status = explode(\':\', $result); // Explode het resultaat. if($status[0] == \'FAIL\'){ // Als het inloggen mislukt is if($num_getLogintries > 0){ // Als er al eens foutief is ingelogd. if($logintries[\'logintries\'] == 2){ // Als er al 2 keer iets fout is gegaan bij het inloggen $db->query(\"UPDATE logintries SET logintries = \'3\', tillTimestap=\'\" . time()+60*15 . \"\' WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); // Maak het aantla loginpogingen 3 en maak een timestamp van een kwartier later }else{ $db->query(\"UPDATE logintries SET logintries = logintries+1 WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); // Tel 1 op bij het aantal foutieve inlogpogingen } }else{ $db->query(\"INSERT INTO logintries(logintries, tillTimestamp) VALUES (\'1\', \'\')\"); // Sla 1 foutieve loginpoging op. } echo \'Het inloggen is mislukt.\' }else{ $db->query(\"DELETE FROM logintries WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); // Er is succesvol ingelogd dus alle foutive pogingen kunnen weg. echo \'Ingelogd\'; } } }else{ echo $form; // Het formulier is niet gepost dus laat het zien. } ?>
Het bestand om te kijken of iemand ingelogd is:
Hier schrijven we gewoon een functie voor:
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
<?php function isLoggedin(){ if(isset($_COOKIE[\'hash\'])){ // Bestaat de cookie? $query = $db->query(\"SELECT hash FROM hashes WHERE userip=\'\" . $_SERVER[\'REMOTE_ADDR\'] . \"\'\"); $num = $db->numRows($query); // We halen de hash op waar het ip gelijk is aan het ip van de bezoeker en tellen de resultaten. if($num == 0){ // We vinden niks maar er bestaat wel een cookie dus die verwijderen we ook gelijk. setcookie(\'hash\', \'\', time()-3600*24*365); // We pakken de cookie hash en verwijderen hem. return false; // De cookie bestaat maar de hash is nergens te vinden dus deze persoon is niet ingelogd. }else{ $fetch = $db->fetchAssoc($query); // We halen de hash op om die te vergelijken met die in de cookie. if($_COOKIE[\'hash\'] == $fetch[\'hash\']){ // We vergelijken de hashes return true; // De hash klopt. en het ip klopt, dus deze persoon is ingelogd. }else{ setcookie(\'hash\', \'\', time()-3600*24*365); // We pakken de cookie hash en verwijderen hem. return false; // De hash klopt niet maar het IP wel dus we verwijderen de cookie. } } }else{ return false; // De cookie bestaat niet dus deze persoon is niet ingelogd. } } ?>
3: Als laatste moet je doen:
Op pagina\'s kijk je of de gebruiker is ingelogd en als dit zo is dat maak je een nieuwe hash dus de timestamp verandert en het random getal verandert.
4: Wat is hier zo veilig aan:
1. We gebruiken SSL dus er kan niet zomaar informatie van het verzonden formulier onderschept worden.
2. We vertragen het inloggen altijd met 1 seconde waardoor het dus altijd langer dan 1 seconde duurt om in te loggen.
3. De zorgen dat je maximaal 3x per kwartier kan proberen in te loggen.
4. We maken een hash die bijna niet na te maken is waardoor de cookie bijna niet na te maken is.
5. We kijken ook wie de echte \"eigenaar\" van de cookie is via het IP dus kan die cookie ook niet gestolen worden.
De opbouw:
We maken een hash en die slaan we op in de DB samen met het ip waarop de hash gemaakt is, updaten deze bij elk bezoek zodat het nog moeilijker is om te jatten.
--------------------------------------------
De SQL kan je zelf wel verzinnen hoop ik.
Commentaar is altijd welkom.
PS: Niet getest dus bugjes kunnen voorkomen, deze code is niet om te kopieren en te plakken maar om er wat van te leren!