[Tutorial PHP]Script de autentificare login

#1
Nume Tutorial:Script de autentificare login
Descriere:Script de autentificare login
Download:Nu necesita
Autor:In script
Sursa (Link-ul oficial):
tutorialeonline.net
Propria parere:Util.
Tutorialul:
Încep aici un tutorial despre ce ar trebui să conţină un script bun de autentificare (login), nu o să scriu cod de data asta, ci o să prezint doar teoria şi logica codului, eventual şi prezentarea tabelelor necesare pentru o autentificare sigură. Nu o să detaliez prea mult pe partea de securitate, deoarece un alt colaborator a scris un tutorial destul de detaliat despre securitate pe care îl găsiţi tot pe acest site.

Ce ar trebui să conţină un script de autentificare

Un script de autentificare conţine un formular de login (viewer), o parte de control a datelor (controler) şi o parte de acces la baza de date (model).
Încep prin a discuta întâi despre formularul de login.
- În funcţie de specificul site-ului şi de necesităţi formularul ar trebui să conţină următoarele câmpuri:
a) Nume utilizator (user)
b) Parola
c) Email
d) Captcha (o poză cu un cod generat aleator)
e) Ecuaţie matematică
f) Hidden user (checkbox)
g) Conectare permanentă (checkbox)
h) Buton de submit
i) Link pentru înregistrare user nou
j) Link pentru lost password

Desigur, nu toate câmpurile de mai sus sunt necesare la un site, cum am spus, depinde de fiecare situaţie în parte.
Astfel, ar trebui gândit scriptul ca să afişeze doar acele câmpuri necesare pentru site-ul curent şi desigur să facă verificările doar după câmpurile care sunt afişate. Pentru asta este nevoie de un mic panou de control pentru administrarea acestor câmpuri, şi în funcţie de specificul site-ului, se pot afişa sau scoate din câmpurile existente.
Noi ne rezumăm la cod, aşa că setam o variabilă de tip array cu TRUE sau FALSE pentru fiecare câmp care dorim să îl afişăm, iar la afişare verificăm ce conţine acest array şi afişăm în consecinţă doar câmpurile setate pe TRUE.
Cod:

Cod: Selectaţi tot

 <?php
 $setari_form_login = array(
 'user' => TRUE,
 'password' => TRUE,
 'email' => FALSE,
 'captcha' => FALSE,
 'math' => FALSE,
 'hidden' => TRUE,
 'forewer' => TRUE,
 'new_acc' => TRUE,
 'lost_pasw' => TRUE);
 ?>
Astfel la afişare şi la verificarea datelor primite din form ne bazăm pe aceste setări şi verificăm doar câmpurile setate pe true.
Trecând la partea de control, preluăm datele trimise din form şi începem verificările. Aici desigur, ne întrebăm ce verificări trebuie făcute. Sigur nu vă gândiţi la ce urmează (:-D

- Pentru partea de verificare, avem aşa:

a) verificare dacă au fost trimise datele cerute, poate nu a fost completat un câmp sau email-ul nu e corect, sau codul captcha.
- dacă apar erori la pasul acesta, se sare peste restul codului şi se afişează din nou formularul împreună cu mesajele de eroare.
b) se verifică numărul de încercări de login efectuate de userul curent în interval de x minute (15 minute eu zic că sunt de ajuns), poate e un boot care e pus să încerce combinaţii de user/parolă până nimereşte una...
- dacă apar erori la pasul acesta, se sare peste restul codului şi se afişează din nou formularul împreună cu mesajele de eroare.
c) se verifică userul şi parola în baza de date şi se preiau datele userului dacă există
- dacă apar erori la pasul acesta, se sare peste restul codului şi se afişează din nou formularul împreună cu mesajele de eroare.
d) având datele userului, verificăm dacă contul e aprobat sau nu (poate că de abia s-a înregistrat şi nu a fost încă activat)
- dacă apar erori la pasul acesta, se sare peste restul codului şi se afişează din nou formularul împreună cu mesajele de eroare.
e) se verifică dacă userul specificat nu este deja logat, poate de pe alt browser sau de la alt ip.
- dacă apar erori la pasul acesta, se sare peste restul codului şi se afişează din nou formularul împreună cu mesajele de eroare.
f) dacă nu sunt erori până la acest pas, se distrug variabilele de sesiune, se reiniţializează sesiunea cu un nou id (pentru evitarea hijak-ului de sesiune) apoi se efectuează autentificarea setând noile valori de sesiune şi eventual cookie. Desigur setăm şi un cod de siguranţă pentru evitarea deturnării sesiunii.
g) se şterg datele de logare din tabelele sql şi se redirectează pentru iniţializarea noilor date de sesiune.
h) userul este autentificat :)

În continuare o să vorbesc mai detaliat despre fiecare punct în parte şi o să prezint tabelele necesare pentru a efectua verificările de mai sus.
Tabelele necesare sunt următoarele:

- Tabelul cu informaţiile userilor (account)
id | user | passwd | email | aprowed | template | language | rights

- Tabelul pentru logare temporar (login_temp)
id | user | email | cod_trimis | cod_setat | browser | ip | timp

- Tabelul pentru useri online (online)
id | user | hidden | page | ip | browser | timp

Acum să luăm fiecare punct în parte şi să discut puţin despre fiecare verificare.

a) Verificarea datelor primite din form. Aici nu avem nevoie de baza de date, doar verificăm dacă user-ul a completat toate câmpurile cerute, eventual verificăm codul captcha şi validitatea adresei de email.
În cazul în care sunt erori la pasul acesta, salvăm datele primite în tabelul "login_temp", (o sa vă spun mai târziu de ce) apoi afişăm eventualele mesaje de avertizare şi îl punem să completeze din nou formularul de login.

b) dacă datele primite sunt corecte, se verifică în tabelul "login_temp" de câte ori a încercat să se logheze în ultimele x minute. Verificarea asta ar fi ceva de genul:
Cod:

Cod: Selectaţi tot

 <?php
 define('TBL_LOGIN_TEMP', 'login_temp'); // numele tabelului
 $wait_minute = 15; // intervalul de verificare
 
 // se compune selectul
 $query = "SELECT count(*) FROM `".TBL_LOGIN_TEMP."`
 WHERE ip = '{$_SERVER['REMOTE_ADDR']}'
 AND browser = '{$_SERVER['HTTP_USER_AGENT']}'
 AND timp > (SELECT DATE_SUB(NOW(), INTERVAL '{$wait_minute}' MINUTE))";
 // se executa interogarea
 // si apoi se preia rezultatul
 // daca a returnat o valoare mai mare decat numarul de incercari permise
 // se afiseaza mesaj de eroare
 // si se iese din switch (sau se opreste executia codului, depinde cum l-ati scris)
 ?>
Rezultatul va fi un număr între 0 şi nr de încercări de logare efectuate de userul respectiv în ultimele $wait_minute.
Mai departe, dacă userul a încercat de prea multe ori să se logheze şi a eşuat (poate fi un boot), salvăm datele de logare în tabelul "login_temp" şi îi scriem mesaj că a depăşit nr maxim de încercări de logare şi să revină dupa x minute :)
Este important să salvaţi datele de logare în tabel după fiecare eroare pentru a evita tentativele de logare la infinit până nimereşte un user şi o parolă valide :)

c) dacă a ajuns la punctul acesta, faceţi o interogare în tabela "account" şi vedeţi dacă user/parola/email (depinde ce trebuie verificat în funcţie de ce e true sau false în variabila array de care am menţionat la început) corespund cu cele trimise. Dacă nu corespund, salvaţi tentativa de login în "login_temp" şi îi afişaţi mesajul de avertizare şi îl puneţi să se logheze din nou. Stresant pentru user, nu? :lol:
Dacă datele sunt corecte, în urma selectului din tabelul "account" avem acum datele userului şi putem merge mai departe.

d) aici verificăm dacă userul curent este aprobat sau nu. Ştiţi voi, treaba aia cu înregistrarea şi apoi confirmarea înregistrării pe email... Eh, până nu confirmă că datele de cont sunt corecte, contul nu e aprobat, deci dacă eşuează la acest punct, salvăm tentativa în "login_temp" şi îi afişăm mesajul corespunzător şi formularul de login.
Este de preferat confirmarea înregistrării contului pe email, astfel se evită înregistrarea boţilor automat, sau adresele de email fictive. Desigur se poate aproba contul şi de un administrator, depinde cum vreţi să faceţi scriptul de activare...

e) La acest punct, trebuie să verificăm dacă nu cumva userul care încearcă să se logheze nu este deja logat, probabil de pe alt ip sau din alt browser... (poate vrea să facă şmecherii şi să testeze securitatea site-ului).
Pentru această verificare avem nevoie de tabelul "online", pur şi simplu facem un select în acest tabel şi vedem dacă userul nu există deja pe site în ultimele 5 minute (5 minute zic eu că e de ajuns pentru a verifica dacă un user este activ pe una din paginile site-ului). Interogarea ar fi cam aşa:
Cod:

Cod: Selectaţi tot

 <?php
 define('TBL_ONLINE', 'online'); // numele tabelului
 $user_id = mysql_real_escape_string($_POST['user']); // numele userului primit din form.
 
 // se compune interogarea
 $query = "SELECT * FROM `".TBL_ONLINE."` WHERE user = '{$user_id}' AND
 timp > (SELECT DATE_SUB(NOW(), INTERVAL '5' MINUTE))";
 ?>
Dacă ne returnează ceva, înseamnă că un user cu acelaşi nume este deja pe site şi nu îl putem lăsa să se conecteze, aşa că îi afişăm mesaj şi îi spunem să revină peste 5 min, că e deja conectat :)
Desigur, salvăm tentativa de logare în "login_temp".

f) dacă am ajuns aici, putem autentifica userul fără probleme.

Desigur, la logout ar trebui curăţate tabelele "online" şi "login_temp", dar eu recomand să faceţi o funcţie pentru asta pe care să o apelaţi în orice pagină, astfel se va curăţa tabelul la fiecare accesare.
N-am cerut la nimeni niciodata,
Chiar de-a fost sa rabd, in viata mea.
Am dat totul fara nici o plata,
Nevoind nimic sa mi se dea.

@Virgil Carianopol
Vezi-ti de treaba si retine:
"E treaba ta sa spui ce vrei si sa nu conteze pentru nimeni".

@Kazi Ploae

Înapoi la “Tutoriale PHP”

Cine este conectat

Utilizatori răsfoind acest forum: Niciun utilizator înregistrat și 0 vizitatori