Slik bruker du brukerautentisering Med Symfony Security Component

I denne artikkelen lærer du hvordan du konfigurerer brukerautentisering i PHP ved hjelp av Symfony Security-komponenten. I tillegg til godkjenning, vil jeg vise deg hvordan du bruker sin rollebaserte autorisasjon, som du kan utvide etter dine behov.

Symfony Security Component

Symfony Security Component lar deg sette opp sikkerhetsfunksjoner som autentisering, rollebasert autorisasjon, CSRF-tokens og mer veldig enkelt. Faktisk er det videre delt inn i fire delkomponenter som du kan velge mellom i henhold til dine behov.

Sikkerhetskomponenten har følgende underkomponenter:

  • symfony / sikkerhets-kjerne
  • symfony / sikkerhet-http
  • symfony / sikkerhet-CSRF
  • symfony / sikkerhet-acl

I denne artikkelen skal vi utforske autentiseringsfunksjonen fra symfony / sikkerhets-kjerne komponent.

Som vanlig begynner vi med installasjons- og konfigurasjonsinstruksjonene, og vi vil utforske noen eksempler på virkelige eksempler for å demonstrere nøkkelbegrepene.

Installasjon og konfigurering

I denne delen skal vi installere Symfony Security-komponenten. Jeg antar at du allerede har installert Komponist på systemet ditt - vi trenger det for å installere Sikkerhetskomponenten tilgjengelig på Packagist.

Så fortsett og installer sikkerhetskomponenten ved hjelp av følgende kommando.

$ komponist krever symfoni / sikkerhet

Vi skal laste brukere fra MySQL-databasen i vårt eksempel, så vi trenger også et databaseabstraksjonslag. La oss installere et av de mest populære databaseabstraksjonslagene: Lære DBAL.

$ komponist krever doktrin / dbal

Det burde ha skapt composer.json fil, som skal se slik ut:

"krav": "sympfony / security": "^ 4.1", "doktrin / dbal": "^ 2.7"

La oss endre composer.json filen for å se ut som den følgende.

"psol-4": "Sfauth \\": "src": "^ 4.1", "doktrine / dbal": "^ 2.7", "autoload" , "klassekart": ["src"]

Som vi har lagt til en ny classmap oppføring, la oss gå videre og oppdatere komponistens autoloader ved å kjøre følgende kommando.

$ komponent dump -o

Nå kan du bruke Sfauth namespace til autoload klasser under src katalog.

Så det er installasjonsdelen, men hvordan skal du bruke den? Faktisk er det bare et spørsmål om å inkludere autoload.php fil opprettet av Komponist i din søknad, som vist i følgende utdrag.

Et eksempel på ekte verden

For det første, la oss gå gjennom den vanlige autentiseringsflyten som tilbys av Symfony Security-komponenten.

  • Det første er å hente brukerens legitimasjon og opprette et uautorisert token.
  • Deretter sender vi et uautorisert token til godkjenningsbehandleren for validering.
  • Autentiseringsadministratoren kan inneholde forskjellige autentiseringsleverandører, og en av dem vil bli brukt til å godkjenne gjeldende brukerforespørsel. Logikken til hvordan brukeren er autentisert er definert i godkjenningsleverandøren.
  • Autentiseringsleverandøren kontakter brukerleverandøren for å hente brukeren. Det er brukerens ansvar å laste brukere fra den respektive back-end.
  • Brukerleverandøren prøver å laste brukeren ved hjelp av legitimasjonene som tilbys av godkjenningsleverandøren. I de fleste tilfeller returnerer brukerleverandøren brukerobjektet som implementerer Brukergrensesnitt grensesnitt.
  • Hvis brukeren er funnet, returnerer autentiseringsleverandøren et uautorisert token, og du kan lagre dette tokenet for de etterfølgende forespørsler.

I vårt eksempel skal vi matche brukerens legitimasjon mot MySQL-databasen, og derfor må vi opprette databasen brukerleverandøren. Vi lager også databasegodkjenningsleverandøren som håndterer godkjenningslogikken. Og til slutt skal vi opprette brukerklassen, som implementerer Brukergrensesnitt grensesnitt.

Brukerklassen

I denne delen skal vi opprette brukerklassen som representerer brukerenheten i autentiseringsprosessen.

Gå videre og opprett src / Bruker / User.php fil med følgende innhold.

brukernavn = $ brukernavn; $ dette-> passord = $ passord; $ this-> roller = $ roller;  offentlig funksjon getUsername () return $ this-> brukernavn;  offentlig funksjon getPassword () return $ this-> passord;  offentlig funksjon getRoles () return explode (",", $ this-> roller);  offentlig funksjon getSalt () return "; offentlig funksjon eraseCredentials () 

Det viktigste er at brukerklassen må implementere Symfony Security Brukergrensesnitt grensesnitt. Bortsett fra det er det ingenting utenom det vanlige her.

Databaseleverandørklassen

Det er brukerens ansvar å laste brukere fra back-end. I denne delen skal vi opprette databasen brukerleverandøren, som laster brukeren fra MySQL-databasen.

La oss lage src / Bruker / DatabaseUserProvider.php fil med følgende innhold.

forbindelse = $ tilkobling;  offentlig funksjon loadUserByUsername ($ brukernavn) return $ this-> getUser ($ brukernavn);  privat funksjon getUser ($ brukernavn) $ sql = "SELECT * FROM sf_users WHERE brukernavn =: navn"; $ stmt = $ this-> connection-> lagre ($ sql); $ stmt-> bindValue ("navn", $ brukernavn); $ Stmt-> utføre (); $ row = $ stmt-> hente (); hvis ! $ rad ['brukernavn']) $ unntak = nytt BrukernavnNotFoundException (sprintf ('Brukernavn% s' ikke funnet i databasen. ', $ rad [' brukernavn '])); $ Unntak-> setUsername ($ username); kaste $ unntak;  ellers returner ny bruker ($ rad ['brukernavn'], $ rad ['passord'], $ rad ['roller']);  offentlig funksjon refreshUser (UserInterface $ bruker) if (! $ user instanceof User) kaste nye UnsupportedUserException (sprintf ('forekomster av% s' støttes ikke. ', get_class ($ user)));  returner $ this-> getUser ($ user-> getUsername ());  offentlige funksjonstjenesterClass ($ class) return 'Sfauth \ User \ User' === $ class; 

Brukerleverandøren må implementere UserProviderInterface grensesnitt. Vi bruker doktor DBAL til å utføre databaselaterte operasjoner. Som vi har implementert UserProviderInterface grensesnitt, må vi implementere loadUserByUsername, refreshUser, og supportsClass fremgangsmåter.

De loadUserByUsername Metoden skal laste brukeren etter brukernavnet, og det er gjort i getUser metode. Hvis brukeren er funnet, returnerer vi det tilsvarende Sfauth \ Bruker \ Bruker objekt, som implementerer Brukergrensesnitt grensesnitt.

På den annen side, refreshUser Metoden oppdaterer den medfølgende Bruker objekt ved å hente siste informasjon fra databasen.

Og til slutt, supportsClass Metode sjekker om DatabaseUserProvider leverandøren støtter den medfølgende brukerklassen.

Databasen Autentiseringsleverandørklasse

Til slutt må vi implementere brukerautentiseringsleverandøren, som definerer autentiseringslogikken - hvordan en bruker er autentisert. I vårt tilfelle må vi matche brukerens legitimasjon mot MySQL-databasen, og dermed må vi definere godkjenningslogikken tilsvarende.

Gå videre og opprett src / Bruker / DatabaseAuthenticationProvider.php fil med følgende innhold.

userProvider = $ userProvider;  beskyttet funksjon hent brukeren ($ brukernavn, BrukernavnPasswordToken $ token) $ user = $ token-> getUser (); hvis ($ user instanceof UserInterface) return $ user;  prøv $ user = $ this-> userProvider-> loadUserByUsername ($ brukernavn); hvis (! $ bruker forekomst av UserInterface) kaste ny AuthenticationServiceException ('Brukerleverandøren må returnere et UserInterface-objekt.');  returner $ bruker;  fangst (UsernameNotFoundException $ e) $ e-> setUsername ($ brukernavn); kaste $ e;  fangst (\ Unntak $ e) $ e = ny AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ E-> setToken ($ token); kaste $ e;  beskyttet funksjonskontrollAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); hvis ($ currentUser instanceof UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) kaste ny AuthenticationException ('Referanser ble endret fra en annen økt.');  else $ password = $ token-> getCredentials (); hvis (tomt ($ passord)) kaste ny AuthenticationException ('Passord kan ikke være tomt.');  hvis ($ user-> getPassword ()! = md5 ($ passord)) kaste ny AuthenticationException ('Passordet er ugyldig.'); 

De DatabaseAuthenticationProvider Autentiseringsleverandøren strekker seg ut UserAuthenticationProvider abstrakt klasse. Derfor må vi implementere retrieveUser og checkAuthentication abstrakte metoder.

Jobben til retrieveUser Metoden er å laste brukeren fra den tilhørende brukerleverandøren. I vårt tilfelle vil det bruke DatabaseUserProvider brukerleverandør for å laste brukeren fra MySQL-databasen.

På den annen side, checkAuthentication Metoden utfører de nødvendige kontrollene for å godkjenne den gjeldende brukeren. Vær oppmerksom på at jeg har brukt MD5-metoden for passordkryptering. Selvfølgelig bør du bruke mer sikre krypteringsmetoder for å lagre brukerpassord.

Slik fungerer det helt

Så langt har vi opprettet alle nødvendige elementer for godkjenning. I denne delen ser vi hvordan du legger alt sammen for å konfigurere autentiseringsfunksjonaliteten.

Gå videre og opprett db_auth.php fil og fyll den med følgende innhold.

 'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME "), ny \ Doctrine \ DBAL \ Configuration ()); // init vår egendefinerte db brukerleverandør $ userProvider = ny DatabaseUserProvider ($ doktrinKonnection); // vi bruker standard UserChecker, den brukes til å sjekke ekstra sjekker som kontoslokk / utløpt etc. // Du kan implementere din egen ved å implementere UserCheckerInterface-grensesnittet $ userChecker = nytt UserChecker (); // init vår egendefinerte db-godkjenningsleverandør $ dbProvider = ny DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // init authentication provider manager $ authenticationManager = ny AuthenticationProviderManager (array ($ dbProvider)); prøv // init un / pw, vanligvis får du disse fra $ _POST-variabelen, sendt av sluttbrukeren $ username = 'admin'; $ password = 'admin'; // få uautorisert token $ unauthenticatedToken = nytt BrukernavnPasswordToken ($ brukernavn, $ passord, 'frontend'); // autentiser bruker og få godkjent token $ authenticatedToken = $ authenticationManager-> autentiser ($ unauthenticatedToken); // Vi har fått godkjent token (brukeren er logget inn nå), den kan lagres i en økt for senere bruk echo $ authenticatedToken; ekko "\ n";  fangst (AuthenticationException $ e) echo $ e-> getMessage (); ekko "\ n"; 

Husk autentiseringsflyten som ble diskutert i begynnelsen av denne artikkelen. Koden ovenfor reflekterer den sekvensen.

Det første var å hente brukerens legitimasjon og opprette et uautorisert token.

$ unauthenticatedToken = nytt BrukernavnPasswordToken ($ brukernavn, $ passord, 'frontend');

Deretter har vi bestått det token til godkjenningsansvarlig for validering.

// autentiser bruker og få godkjent token $ authenticatedToken = $ authenticationManager-> autentiser ($ unauthenticatedToken);

Når autentiseringsmetoden kalles, skjer det mye bak kulissene.

For det første velger autentiseringsadministratoren en passende godkjenningsleverandør. I vårt tilfelle er det DatabaseAuthenticationProvider godkjenningsleverandør, som vil bli valgt for godkjenning.

Deretter hentes brukeren av brukernavnet fra DatabaseUserProvider brukerleverandør. Endelig, den checkAuthentication Metoden utfører de nødvendige kontrollene for å godkjenne gjeldende brukerforespørsel.

Skulle du ønske å teste db_auth.php script, må du opprette sf_users bord i MySQL-databasen.

CREATE TABLE 'sf_users' ('id' int (11) IKKE NULL AUTO_INCREMENT, 'brukernavn' varchar (255) IKKE NULL, 'passord' varchar (255) IKKE NULL, 'roller' enum ('registrert', 'moderator' 'admin') DEFAULT NULL, PRIMARY KEY ('id')) MOTOR = InnoDB; INSERT TIL 'sf_users' verdier (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');

Gå videre og kjøre db_auth.php skript for å se hvordan det går. Ved vellykket gjennomføring bør du motta et godkjent token, som vist i følgende utdrag.

$ php db_auth.php BrukernavnPasswordToken (user = "admin", authenticated = true, roller = "admin")

Når brukeren er autentisert, kan du lagre det autentiserte token i sesjonen for de påfølgende forespørsler.

Og med det har vi fullført vår enkle autentiseringsdemo!

Konklusjon

I dag så vi på komponenten Symfony Security, som lar deg integrere sikkerhetsfunksjoner i dine PHP-applikasjoner. Spesielt diskuterte vi autentiseringsfunksjonen som ble levert av komponenten sympfony / security-core og jeg viste deg et eksempel på hvordan denne funksjonaliteten kan implementeres i din egen app.

Du er velkommen til å legge inn dine tanker ved å bruke feedet under!