Så här gör du användarautentisering Med Symfony Security Component

I den här artikeln lär du dig hur du konfigurerar användarautentisering i PHP med hjälp av Symfony Security-komponenten. Förutom autentisering visar jag dig hur du använder sitt rollbaserade godkännande, som du kan utöka efter dina behov.

Symfony Security Component

Symfony Security Component kan du konfigurera säkerhetsfunktioner som autentisering, rollbaserad auktorisation, CSRF-tokens och mycket enklare. Faktum är att det ytterligare delas upp i fyra delkomponenter som du kan välja ut efter dina behov.

Säkerhetskomponenten har följande delkomponenter:

  • Symfony / säkerhet-core
  • Symfony / säkerhet-http
  • Symfony / säkerhet-CSRF
  • Symfony / säkerhet-acl

I den här artikeln kommer vi att undersöka autentiseringsfunktionen som tillhandahålls av Symfony / säkerhet-core komponent.

Som vanligt börjar vi med installations- och konfigurationsinstruktionerna och sedan utforskar vi några exempel på verkligheten för att visa de centrala begreppen.

Installation och konfiguration

I det här avsnittet ska vi installera Symfony Security-komponenten. Jag antar att du redan har installerat Composer på ditt system - vi måste installera säkerhetskomponenten som finns tillgänglig på Packagist.

Så fortsätt och installera säkerhetskomponenten med följande kommando.

$ komponisten kräver symfoni / säkerhet

Vi ska ladda användare från MySQL-databasen i vårt exempel, så vi behöver också ett databasabstraktionslager. Låt oss installera ett av de mest populära databasabstraktionslagren: Läran DBAL.

$ kompositör kräver doktrin / dbal

Det borde ha skapat composer.json fil som ska se ut så här:

"kräver": "symfony / security": "^ 4.1", "doktrin / dbal": "^ 2.7"

Låt oss ändra composer.json filen för att se ut som följande.

"psol-4": "Sfauth \\": "src": "^" , "klasskarta": ["src"]

Som vi har lagt till en ny classMap inträde, låt oss fortsätta och uppdatera kompositörens autoloader genom att köra följande kommando.

$ kompositör dumpa -o

Nu kan du använda Sfauth namnrymd till autoload klasser under src katalog.

Så det är installationsdelen, men hur ska du använda den? Faktum är att det bara handlar om att inkludera autoload.php fil skapad av kompositören i din ansökan, som visas i följande kod.

Ett verkligt exempel på världen

För det första, låt oss gå igenom det vanliga autentiseringsflödet som tillhandahålls av Symfony Security-komponenten.

  • Det första är att hämta användaruppgifter och skapa en oautentiserad token.
  • Därefter skickar vi en autentiserad token till autentiseringshanteraren för validering.
  • Autentiseringshanteraren kan innehålla olika autentiseringsleverantörer, och en av dem kommer att användas för att autentisera den aktuella användarförfrågan. Logiken för hur användaren är autentiserad definieras i autentiseringsleverantören.
  • Autentiseringsleverantören kontaktar användarleverantören för att hämta användaren. Det är användarens leverantörs ansvar att ladda användare från respektive back-end.
  • Användarleverantören försöker ladda användaren med hjälp av uppgifterna från autentiseringsleverantören. I de flesta fall returnerar användarleverantören det användarobjekt som implementerar Användargränssnitt gränssnitt.
  • Om användaren återfinns returnerar autentiseringsleverantören ett oautentiserat token och du kan lagra denna token för de efterföljande förfrågningarna.

I vårt exempel kommer vi att matcha användaruppgifterna mot MySQL-databasen, så vi måste skapa databasleverantören. Vi skapar också databasens autentiseringsleverantör som hanterar autentiseringslogiken. Och slutligen ska vi skapa användarklassen, som implementerar Användargränssnitt gränssnitt.

Användarklassen

I det här avsnittet skapar vi användarklassen som representerar användarorganisationen i autentiseringsprocessen.

Gå vidare och skapa src / User / user.php fil med följande innehåll.

användarnamn = $ användarnamn; $ this-> password = $ password; $ this-> roller = $ roller;  allmän funktion getUsername () return $ this-> användarnamn;  offentlig funktion getPassword () returnera $ this-> lösenord;  public function getRoles () return explodera (",", $ this-> roller);  allmän funktion getSalt () return "; public function eraseCredentials () 

Det viktiga är att användarklassen måste implementera Symfony Security Användargränssnitt gränssnitt. Bortsett från det finns det inget ovanligt här.

Databasleverantörsklassen

Det är användarens leverantörs ansvar att ladda användare från back-end. I det här avsnittet skapar vi databasleverantören, som laddar användaren från MySQL-databasen.

Låt oss skapa src / User / DatabaseUserProvider.php fil med följande innehåll.

anslutning = $ anslutning;  allmän funktion loadUserByUsername ($ användarnamn) return $ this-> getUser ($ användarnamn);  privat funktion getUser ($ användarnamn) $ sql = "SELECT * FROM sf_users WHERE användarnamn =: namn"; $ stmt = $ this-> connection-> förbereda ($ sql); $ stmt-> bindValue ("namn", $ användarnamn); $ Stmt-> execute (); $ row = $ stmt-> hämta (); om ! $ row ['användarnamn']) $ exception = new UsernameNotFoundException (sprintf ('Användarnamn'% s "hittades inte i databasen. ', $ row [' användarnamn '])); $ I undantags> setUsername ($ användarnamn); kasta $ undantag;  annars returnera ny användare ($ rad ['användarnamn'], $ rad ['lösenord'], $ rad ['roller']);  public function refreshUser (UserInterface $ user) if (! $ user instanceof User) kasta nytt UnsupportedUserException (sprintf ('Instanser av% s' stöds inte. ', get_class ($ user)));  returnera $ this-> getUser ($ user-> getUsername ());  public function supportsClass ($ class) returnera 'Sfauth \ User \ User' === $ class; 

Användarleverantören måste implementera UserProviderInterface gränssnitt. Vi använder doktrinen DBAL för att utföra databasrelaterade operationer. Som vi har genomfört UserProviderInterface gränssnitt, måste vi genomföra loadUserByUsername, refreshUser, och supportsClass metoder.

De loadUserByUsername Metod bör ladda användaren av användarnamnet, och det är gjort i getUser metod. Om användaren hittas returnerar vi motsvarande Sfauth \ Användare \ Användare objekt som implementerar Användargränssnitt gränssnitt.

Å andra sidan, refreshUser Metoden uppdaterar den medföljande Användare objekt genom att hämta den senaste informationen från databasen.

Och äntligen supportsClass Metoden kontrollerar om DatabaseUserProvider leverantören stöder den medföljande användarklassen.

Databasautentiseringsleverantörsklassen

Slutligen måste vi implementera användarautentiseringsleverantören, som definierar autentiseringslogiken-hur en användare är autentiserad. I vårt fall måste vi matcha användaruppgifterna mot MySQL-databasen, och därmed måste vi definiera autentiseringslogiken i enlighet med detta.

Gå vidare och skapa src / User / DatabaseAuthenticationProvider.php fil med följande innehåll.

userProvider = $ userProvider;  skyddad funktion hämtaUser ($ användarnamn, AnvändarnamnPasswordToken $ token) $ user = $ token-> getUser (); om ($ user instanceof UserInterface) return $ user;  försök $ user = $ this-> userProvider-> loadUserByUsername ($ användarnamn); om (! $ användarens instans av UserInterface) släng ny AuthenticationServiceException ('Användarleverantören måste returnera ett UserInterface-objekt.');  returnera $ användaren;  fånga (UsernameNotFoundException $ e) $ e-> setUsername ($ användarnamn); kasta $ e;  fångst (\ Undantag $ e) $ e = ny AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ E-> setToken ($ token); kasta $ e;  skyddad funktion checkAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); om $ currentUser instanceof UserInterface if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) kasta ny AuthenticationException ('Referenser ändrades från en annan session.');  else $ password = $ token-> getCredentials (); om (tomt ($ lösenord)) släng nytt AuthenticationException ('Lösenordet kan inte vara tomt');  om ($ user-> getPassword ()! = md5 ($ lösenord)) släng ny AuthenticationException ('Lösenordet är ogiltigt.'); 

De DatabaseAuthenticationProvider autentiseringsleverantören utökar UserAuthenticationProvider abstrakt klass. Därför måste vi genomföra retrieveUser och checkAuthentication abstrakta metoder.

Arbetet hos retrieveUser Metoden är att ladda användaren från motsvarande användarleverantör. I vårt fall kommer det att använda DatabaseUserProvider användarleverantör för att ladda användaren från MySQL-databasen.

Å andra sidan, checkAuthentication Metoden utför de nödvändiga kontrollerna för att autentisera den nuvarande användaren. Observera att jag har använt MD5-metoden för kryptering av lösenord. Självklart borde du använda säkrare krypteringsmetoder för att lagra användarlösenord.

Hur det fungerar helt och hållet

Hittills har vi skapat alla nödvändiga element för autentisering. I det här avsnittet ser vi hur du sammanfattar allt för att konfigurera autentiseringsfunktionen.

Gå vidare och skapa db_auth.php fil och fyll i den med följande innehåll.

 'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME "), ny \ doktrin \ DBAL \ Configuration ()); // init vår anpassade db-användarleverantör $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // vi använder standard UserChecker, det används för att kontrollera ytterligare kontroller som kontonlås / utgått etc. // Du kan implementera din egen genom att implementera UserCheckerInterface-gränssnittet $ userChecker = nytt UserChecker (); // init vår anpassade db-verifieringsleverantör $ dbProvider = ny DatabaseAuthenticationProvider ($ userProvider, $ userChecker, frontend); // init authentication provider manager $ authenticationManager = ny AuthenticationProviderManager (array ($ dbProvider)); försök // init un / pw, vanligtvis får du dessa från variabel $ _POST, som skickas av slutanvändaren $ username = 'admin'; $ password = 'admin'; // få oautentiserad token $ unauthenticatedToken = nytt AnvändarnamnPasswordToken ($ användarnamn, $ lösenord, 'frontend'); // autentisera användaren och få autentiserad token $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken); // Vi har fått autentiserad token (användaren är inloggad nu), den kan lagras i en session för senare användning echo $ authenticatedToken; eko "\ n";  fånga (AuthenticationException $ e) echo $ e-> getMessage (); eko "\ n"; 

Minns det autentiseringsflöde som diskuterades i början av denna artikel-ovanstående kod återspeglar den sekvensen.

Det första var att hämta användaruppgifter och skapa en oautentiserad token.

$ unauthenticatedToken = nytt AnvändarnamnPasswordToken ($ användarnamn, $ lösenord, 'frontend');

Därefter har vi skickat det token till autentiseringshanteraren för validering.

// autentisera användaren och få autentiserad token $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken);

När autentiseringsmetoden heter, händer många saker bakom kulisserna.

För det första väljer autentiseringshanteraren en lämplig autentiseringsleverantör. I vårt fall är det DatabaseAuthenticationProvider autentiseringsleverantör, som kommer att väljas för autentisering.

Därefter hämtar användaren användarnamnet från DatabaseUserProvider användarleverantör. Slutligen, den checkAuthentication Metoden utför de nödvändiga kontrollerna för att autentisera den aktuella användarförfrågan.

Skulle du vilja testa db_auth.php script, du måste skapa sf_users bord i din MySQL-databas.

CREATE TABLE 'sf_users' ('id' int (11) INTE NULL AUTO_INCREMENT, 'användarnamn' varchar (255) INTE NULL, 'lösenord' varchar (255) INTE NULL, 'roller' enum ('registered', 'moderator' 'admin') DEFAULT NULL, PRIMARY KEY ('id')) MOTOR = InnoDB; INSERT INTO 'sf_users' värden (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');

Fortsätt och springa db_auth.php manus för att se hur det går. Vid framgångsrik slutförande bör du få en autentiserad token, som visas i följande kod.

$ php db_auth.php AnvändarnamnPasswordToken (user = "admin", authenticated = true, roles = "admin")

När användaren är autentiserad kan du lagra det autentiserade token i sessionen för efterföljande förfrågningar.

Och med det har vi slutfört vår enkla autentiseringsdemo!

Slutsats

Idag tittade vi på komponenten Symfony Security, som låter dig integrera säkerhetsfunktioner i dina PHP-applikationer. Specifikt diskuterade vi autentiseringsfunktionen som tillhandahålls av komponenten sympfony / security-core och jag visade dig ett exempel på hur denna funktionalitet kan implementeras i din egen app.

Skicka gärna dina tankar med foderet nedan!