În acest articol, veți învăța cum să configurați autentificarea utilizatorilor în PHP utilizând componenta Symfony Security. Pe lângă autentificare, vă voi arăta cum să utilizați autorizarea bazată pe rol, pe care o puteți extinde în funcție de nevoile dvs..
Componenta de securitate Symfony vă permite să configurați funcții de securitate precum autentificarea, autorizarea bazată pe roluri, jetoanele CSRF și mai ușor. De fapt, este în continuare împărțit în patru sub-componente pe care le puteți alege în funcție de nevoile dvs..
Componenta de securitate are următoarele subcomponente:
În acest articol, vom explora caracteristica de autentificare oferită de Symfony / securitate-core component.
Ca de obicei, vom începe cu instrucțiunile de instalare și configurare și apoi vom explora câteva exemple din lumea reală pentru a demonstra conceptele cheie.
În această secțiune, vom instala componenta Symfony Security. Presupun că ați instalat deja Compozitor în sistemul dvs. - vom avea nevoie de el pentru a instala componenta de securitate disponibilă la Packagist.
Deci, mergeți mai departe și instalați componenta de securitate utilizând următoarea comandă.
Compozitorul $ necesită simfonie / securitate
Vom încărca utilizatorii din baza de date MySQL în exemplul nostru, deci avem nevoie și de un strat de abstractizare a bazei de date. Să instalați unul dintre cele mai populare straturi de abstractizare a bazei de date: Doctrină DBAL.
$ compozitorul cere doctrină / dbal
Ar fi trebuit să creeze composer.json fișier, care ar trebui să arate astfel:
"necesită": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7"
Să modificăm composer.json fișierul să arate ca unul următor.
"necesită": "simfony / security": "^ 4.1", "doctrine / dbal" , "classmap": ["src"]
Așa cum am adăugat un nou classmap
intrare, să mergem mai departe și să actualizăm autoloaderul compozitorului executând următoarea comandă.
comisionul compozitorului $ -o
Acum, puteți folosi Sfauth
spațiu de nume la clasele de autoreglare în cadrul src director.
Deci asta este partea de instalare, dar cum ar trebui să o folosești? De fapt, este doar o chestiune de a include autoload.php fișier creat de Compozitor în aplicația dvs., așa cum se arată în fragmentul următor.
În primul rând, hai să trecem prin fluxul obișnuit de autentificare furnizat de componenta Symfony Security.
Interfața cu utilizatorul
interfață.În exemplul nostru, vom potrivi acreditările utilizatorului cu baza de date MySQL, astfel că va trebui să creați furnizorul de servicii de bază de date. De asemenea, vom crea furnizorul de autentificare a bazei de date care gestionează logica de autentificare. În final, vom crea clasa Utilizator, care implementează Interfața cu utilizatorul
interfață.
În această secțiune, vom crea clasa utilizator care reprezintă entitatea utilizatorului în procesul de autentificare.
Continuați și creați src / utilizator / User.php fișier cu următorul conținut.
username = $ username; $ this-> password = $ parola; $ this-> roles = $ roluri; funcția publică getUsername () return $ this-> username; funcția publică getPassword () return $ this-> password; funcția publică getRoles () return explodează (",", $ this-> roles); funcția publică getSalt () return "; funcția publică eraseCredentials ()
Lucrul important este că clasa utilizator trebuie să implementeze sistemul de securitate Symfony Interfața cu utilizatorul
interfață. În afară de asta, nu e nimic neobișnuit aici.
Este responsabilitatea furnizorului de a încărca utilizatorii din back-end. În această secțiune, vom crea furnizorul de baze de date, care îl încarcă pe utilizator din baza de date MySQL.
Să creăm src / utilizator / DatabaseUserProvider.php fișier cu următorul conținut.
conexiune = $ conexiune; funcția publică loadUserByUsername ($ username) return $ this-> getUser ($ username); funcția privată getUser ($ username) $ sql = "SELECT * FROM sf_users WHERE username =: nume"; $ stmt = $ this-> conexiune-> pregăti ($ sql); $ stmt-> bindValue ("nume", $ username); $ Stmt-> execute (); $ rând = $ stmt-> preluare (); dacă ! $ row ['username']) $ exception = new NumeNotFoundException (sprintf ("Utilizator"% s "nu a fost găsit în baza de date"; $ row ['username'])); $ Excepțional de> setUsername ($ username); arunca $ exception; altfel returnează un utilizator nou ($ row ['username'], $ row ['password'], $ row ['roles']); funcția publică refreshUser (UserInterface $ user) if ($ user instanceof User) arunca noul UnsupportedUserException (sprintf ('Instanțele lui "% s" nu sunt acceptate. return $ this-> getUser ($ user-> getUsername ()); funcția publică supportsClass ($ class) returnează 'Sfauth \ User \ User' === $ class;
Furnizorul de utilizator trebuie să implementeze UserProviderInterface
interfață. Utilizăm doctrina DBAL pentru a efectua operațiile bazate pe bază de date. După cum am implementat UserProviderInterface
interfață, trebuie să punem în aplicare loadUserByUsername
, refreshUser
, și supportsClass
metode.
loadUserByUsername
metoda ar trebui să încarce utilizatorul după numele de utilizator, și asta se face în getUser
metodă. Dacă utilizatorul este găsit, returnează suma corespunzătoare Sfauth \ utilizator \ utilizator
obiect, care implementează Interfața cu utilizatorul
interfață.
Pe de altă parte, refreshUser
metoda actualizează produsul furnizat Utilizator
obiecte prin preluarea celor mai recente informații din baza de date.
Și, în final, supportsClass
metoda verifică dacă DatabaseUserProvider
furnizorul acceptă clasa de utilizatori furnizată.
În cele din urmă, trebuie să implementăm furnizorul de autentificare a utilizatorului, care definește logica autentificării - modul în care un utilizator este autentificat. În cazul nostru, trebuie să se potrivească acreditările utilizatorului cu baza de date MySQL și, prin urmare, trebuie să definim logica de autentificare.
Continuați și creați src / utilizator / DatabaseAuthenticationProvider.php fișier cu următorul conținut.
userProvider = $ userProvider; funcția protejată retrieveUser ($ username, UsernamePasswordToken $ token) $ user = $ token-> getUser (); dacă ($ user instanceof UserInterface) return $ user; încercați $ user = $ this-> userProvider-> loadUserByUsername ($ username); if ($ user instanceof UserInterface) arunca noul AuthenticationServiceException ('Furnizorul de utilizator trebuie să returneze un obiect UserInterface.'); return $ user; captură (NumeNotFoundExcepție $ e) $ e-> setUsername ($ username); arunca $ e; captură (\ Excepție $ e) $ e = nouă AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ E> setToken ($ token); arunca $ e; funcția protejată checkAuthentication (UserInterface $ user, NumePasswordToken $ token) $ currentUser = $ token-> getUser (); dacă ($ currentUser instanceof UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) aruncați o nouă AuthenticationException ("Au fost schimbate acreditările dintr-o altă sesiune"; altceva $ password = $ token-> getCredentials (); if (empty ($ password)) arunca noua AuthenticationException ("Parola nu poate fi goala"); dacă ($ user-> getPassword ()! = md5 ($ password)) arunca noua AuthenticationException ("Parola nu este validă");
DatabaseAuthenticationProvider
furnizorul de autentificare extinde UserAuthenticationProvider
clasă abstractă. Prin urmare, trebuie să punem în aplicare retrieveUser
și checkAuthentication
metode abstracte.
Locul de muncă al retrieveUser
metoda este de a încărca utilizatorul de la furnizorul de servicii corespunzător. În cazul nostru, va folosi DatabaseUserProvider
utilizator pentru a încărca utilizatorul din baza de date MySQL.
Pe de altă parte, checkAuthentication
metoda efectuează verificările necesare pentru autentificarea utilizatorului curent. Rețineți că am folosit metoda MD5 pentru criptarea parolei. Desigur, ar trebui să utilizați metode de criptare mai sigure pentru a stoca parolele utilizatorilor.
Până acum, am creat toate elementele necesare autentificării. În această secțiune, vom vedea cum să le punem împreună pentru a configura funcția de autentificare.
Continuați și creați db_auth.php fișier și o populează cu următorul conținut.
'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME'), noul \ Doctrine \ DBAL \ Configuration ()); // init furnizorul de servicii custom db $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // vom folosi UserChecker implicit, este folosit pentru a verifica verificări suplimentare cum ar fi blocarea contului / expirat etc. // puteți implementa propria dvs. prin implementarea interfeței UserCheckerInterface $ userChecker = nou UserChecker (); // init furnizorul nostru de autentificare db personalizat $ dbProvider = new DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // administrator de autentificare de autentificare init $ authenticationManager = new AuthenticationProviderManager (array ($ dbProvider)); încercați // init un / pw, de obicei le veți primi din variabila $ _POST, trimisă de utilizatorul final $ username = 'admin'; $ password = 'admin'; // a obține tokenul neautentificat $ unauthenticatedToken = noul UsernamePasswordToken ($ username, $ password, 'frontend'); // autentificați utilizatorul și obțineți jeton autentificat $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken); // am primit jetonul autentificat (utilizatorul este conectat acum), poate fi stocat într-o sesiune pentru o utilizare ulterioară echo $ authenticatedToken; echo "\ n"; captură (AuthenticationException $ e) echo $ e-> getMessage (); echo "\ n";
Amintiți-vă fluxul de autentificare care a fost discutat la începutul acestui articol - codul de mai sus reflectă acea secvență.
Primul lucru a fost să preluați acreditările utilizatorilor și să creați un jeton neautentificat.
$ unauthenticatedToken = nume de utilizator nouPasswordToken ($ username, $ password, 'frontend');
Apoi, am trecut acel jeton la managerul de autentificare pentru validare.
// autentificați utilizatorul și obțineți jeton autentificat $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken);
Când se numește metoda de autentificare, multe lucruri se întâmplă în spatele scenei.
În primul rând, managerul de autentificare selectează un furnizor de autentificare adecvat. În cazul nostru, este vorba de DatabaseAuthenticationProvider
furnizor de autentificare, care va fi selectat pentru autentificare.
Apoi, utilizatorul recuperează numele de utilizator din DatabaseUserProvider
utilizator. În cele din urmă, checkAuthentication
metoda efectuează verificările necesare pentru autentificarea cererii curente de utilizator.
Dacă doriți să testați db_auth.php script, va trebui să creați sf_users
tabel în baza de date MySQL.
CREATE TABLE 'sf_users' ('id' int (11) NOT NULL AUTO_INCREMENT, 'username' varchar (255) NOT NULL, 'parola' varchar (255) NOT NULL, 'admin') DEFAULT NULL, KEY PRIMARY ('id')) MOTOR = InnoDB; INSCRIEȚI ÎN VALORILE "sf_users" (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');
Mergeți și conduceți db_auth.php script pentru a vedea cum merge. După finalizarea cu succes, ar trebui să primiți un token autentificat, așa cum se arată în fragmentul următor.
$ php db_auth.php Nume utilizatorPasswordToken (user = "admin", autentificat = true, roluri = "admin")
Odată ce utilizatorul este autentificat, puteți stoca tokenul autentificat în sesiune pentru solicitările ulterioare.
Și cu asta, am finalizat demo-ul nostru simplu de autentificare!
Astăzi, am analizat componenta Symfony Security, care vă permite să integrați caracteristicile de securitate în aplicațiile dvs. PHP. Mai exact, am discutat despre caracteristica de autentificare furnizată de subcomponenta simfony / security-core și am arătat un exemplu despre modul în care această funcționalitate poate fi implementată în propria dvs. aplicație.
Simțiți-vă liber să vă postați gândurile folosind feed-ul de mai jos!