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 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:
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.
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.
För det första, låt oss gå igenom det vanliga autentiseringsflödet som tillhandahålls av Symfony Security-komponenten.
Användargränssnitt
gränssnitt.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.
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.
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.
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.
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!
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!