In dit artikel leert u hoe u gebruikersverificatie instelt in PHP met behulp van de Symfony-beveiligingscomponent. Naast authenticatie zal ik u laten zien hoe u de rolgebaseerde autorisatie gebruikt, die u kunt uitbreiden op basis van uw behoeften.
Met de Symfony-beveiligingscomponent kunt u zeer eenvoudig beveiligingsfuncties instellen zoals verificatie, op rollen gebaseerde autorisatie, CSRF-tokens en meer. In feite is het verder onderverdeeld in vier subcomponenten waaruit u kunt kiezen op basis van uw behoeften.
De beveiligingscomponent heeft de volgende subcomponenten:
In dit artikel gaan we op zoek naar de authenticatiefunctie van de symfony / security-core bestanddeel.
Zoals gewoonlijk beginnen we met de installatie- en configuratie-instructies, en vervolgens verkennen we enkele praktijkvoorbeelden om de belangrijkste concepten te demonstreren.
In deze sectie gaan we de Symfony Security-component installeren. Ik neem aan dat u Composer al op uw systeem hebt geïnstalleerd. We hebben het nodig om de beveiligingscomponent die beschikbaar is op Packagist te installeren.
Dus ga je gang en installeer de beveiligingscomponent met behulp van de volgende opdracht.
$ componist vereist symfony / veiligheid
We laden gebruikers uit de MySQL-database in ons voorbeeld, dus we hebben ook een database-abstractielaag nodig. Laten we een van de meest populaire database-abstractielagen installeren: Doctrine DBAL.
$ componist vereist doctrine / dbal
Dat zou de composer.json bestand, dat er als volgt uit moet zien:
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7"
Laten we het aanpassen composer.json bestand om er als volgt uit te zien.
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7", "autoload": "psr-4": "Sfauth \\": "src" , "classmap": ["src"]
Omdat we een nieuwe hebben toegevoegd classmap
invoer, laten we doorgaan en de autoloader van de componist bijwerken door de volgende opdracht uit te voeren.
$ composer dump -o
Nu kunt u de Sfauth
naamruimte om klassen autoload onder de src directory.
Dus dat is het installatiedeel, maar hoe moet je het gebruiken? In feite is het gewoon een kwestie van het opnemen van de autoload.php bestand gemaakt door Composer in uw toepassing, zoals getoond in het volgende fragment.
Laten we eerst de gebruikelijke authenticatiestroom doornemen die wordt geboden door de Symfony-beveiligingscomponent.
Gebruikersomgeving
interface.In ons voorbeeld gaan we de gebruikersreferenties vergelijken met de MySQL-database, dus we moeten de database-gebruikersprovider maken. We zullen ook de database-authenticatieprovider maken die de authenticatielogica verwerkt. En tot slot maken we de klasse User, die de. Implementeert Gebruikersomgeving
interface.
In deze sectie maken we de klasse User die de gebruikersentiteit in het authenticatieproces vertegenwoordigt.
Ga je gang en maak de src / User / User.php bestand met de volgende inhoud.
gebruikersnaam = $ gebruikersnaam; $ this-> wachtwoord = $ wachtwoord; $ this-> roles = $ roles; openbare functie getUsername () return $ this-> gebruikersnaam; openbare functie getPassword () return $ this-> wachtwoord; openbare functie getRoles () return explode (",", $ this-> roles); openbare functie getSalt () return "; public function eraseCredentials ()
Het belangrijkste is dat de klasse User de Symfony Security moet implementeren Gebruikersomgeving
interface. Afgezien daarvan is er hier niets bijzonders.
Het is de verantwoordelijkheid van de gebruiker om gebruikers vanaf de back-end te laden. In deze sectie maken we de database-gebruikersprovider, die de gebruiker laadt vanuit de MySQL-database.
Laten we het maken src / User / DatabaseUserProvider.php bestand met de volgende inhoud.
verbinding = $ verbinding; openbare functie loadUserByUsername ($ gebruikersnaam) return $ this-> getUser ($ gebruikersnaam); private function getUser ($ gebruikersnaam) $ sql = "SELECT * FROM sf_users WHERE gebruikersnaam =: name"; $ stmt = $ this-> connection-> prepare ($ sql); $ stmt-> bindValue ("naam", $ gebruikersnaam); $ Stmt-> execute (); $ row = $ stmt-> fetch (); if (! $ row ['gebruikersnaam']) $ exception = new GebruikersnaamNotFoundException (sprintf ('Gebruikersnaam "% s" niet gevonden in de database.', $ row ['gebruikersnaam'])); $ Buitenge-> setUsername ($ username); $ uitzondering gooien; else retourneer nieuwe gebruiker ($ rij ['gebruikersnaam'], $ rij ['wachtwoord'], $ rij ['rollen']); public function refreshUser (UserInterface $ user) if (! $ user instanceof User) throw new UnsupportedUserException (sprintf ('Instances of "% s" worden niet ondersteund.', get_class ($ user))); return $ this-> getUser ($ user-> getUsername ()); public function supportsClass ($ class) ga terug naar 'Sfauth \ User \ User' === $ class;
De gebruikersprovider moet het UserProviderInterface
interface. We gebruiken de doctrine DBAL om de database-gerelateerde bewerkingen uit te voeren. Zoals we de. Hebben geïmplementeerd UserProviderInterface
interface, moeten we de loadUserByUsername
, refreshUser
, en supportsClass
methoden.
De loadUserByUsername
methode moet de gebruiker laden door de gebruikersnaam, en dat gebeurt in de getUser
methode. Als de gebruiker wordt gevonden, retourneren we de bijbehorende Sfauth \ User \ User
object, dat het Gebruikersomgeving
interface.
Aan de andere kant, de refreshUser
methode ververst de meegeleverde Gebruiker
object door de nieuwste informatie uit de database op te halen.
En tot slot, de supportsClass
methode controleert of de DatabaseUserProvider
provider ondersteunt de geleverde gebruikersklasse.
Ten slotte moeten we de provider voor gebruikersverificatie implementeren, die de authenticatielogica definieert - hoe een gebruiker wordt geverifieerd. In ons geval moeten we de gebruikersreferenties vergelijken met de MySQL-database en daarom moeten we de authenticatielogica dienovereenkomstig definiëren.
Ga je gang en maak de src / User / DatabaseAuthenticationProvider.php bestand met de volgende inhoud.
userProvider = $ userProvider; beschermde functie retrieveUser ($ gebruikersnaam, GebruikersnaamPasswordToken $ token) $ user = $ token-> getUser (); if ($ user instanceof UserInterface) return $ user; probeer $ user = $ this-> userProvider-> loadUserByUsername ($ gebruikersnaam); if (! $ user instanceof UserInterface) gooi nieuwe AuthenticationServiceException ('De gebruiker moet een UserInterface-object retourneren.'); return $ gebruiker; catch (GebruikersnaamNotFoundException $ e) $ e-> setUsername ($ gebruikersnaam); werp $ e; catch (\ Uitzondering $ e) $ e = nieuwe AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ E-> setToken ($ token); werp $ e; beschermde functie checkAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); if ($ currentUser instance of UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) gooi nieuwe AuthenticationException ('Referenties zijn gewijzigd van een andere sessie.'); else $ password = $ token-> getCredentials (); if (empty ($ password)) throw new AuthenticationException ('Wachtwoord mag niet leeg zijn'); if ($ user-> getPassword ()! = md5 ($ wachtwoord)) gooi nieuwe AuthenticationException ('Wachtwoord is ongeldig.');
De DatabaseAuthenticationProvider
authenticatie provider breidt het UserAuthenticationProvider
abstracte klasse. Daarom moeten we het retrieveUser
en checkAuthentication
abstracte methoden.
De taak van de retrieveUser
methode is om de gebruiker te laden van de bijbehorende gebruikersprovider. In ons geval gebruikt het de DatabaseUserProvider
gebruikersprovider om de gebruiker vanuit de MySQL-database te laden.
Aan de andere kant, de checkAuthentication
methode voert de nodige controles uit om de huidige gebruiker te verifiëren. Houd er rekening mee dat ik de MD5-methode heb gebruikt voor wachtwoordversleuteling. U moet natuurlijk veiligere versleutelingsmethoden gebruiken om gebruikerswachtwoorden op te slaan.
Tot dusverre hebben we alle noodzakelijke elementen voor authenticatie gecreëerd. In deze sectie zullen we zien hoe we alles samen kunnen stellen om de authenticatiefunctionaliteit in te stellen.
Ga je gang en maak de db_auth.php bestand en vul het met de volgende inhoud.
'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME'), new \ Doctrine \ DBAL \ Configuration ()); // start onze aangepaste db-gebruikersprovider $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // we zullen standaard UserChecker gebruiken, het wordt gebruikt om extra controles te controleren, zoals accountvergrendeling / verlopen enz. // u kunt uw eigen controles uitvoeren door UserCheckerInterface-interface te implementeren $ userChecker = new UserChecker (); // start onze aangepaste db-authenticatieprovider $ dbProvider = new DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // init authentication provider manager $ authenticationManager = nieuwe AuthenticationProviderManager (array ($ dbProvider)); probeer // init un / pw, meestal krijg je deze van de variabele $ _POST, ingediend door de eindgebruiker $ username = 'admin'; $ wachtwoord = 'admin'; // ontvang niet-geverifieerd token $ unauthenticatedToken = new UsernamePasswordToken ($ gebruikersnaam, $ wachtwoord, 'frontend'); // authenticate user & get authenticated token $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken); // we hebben het geverifieerde token (gebruiker is nu ingelogd), het kan worden opgeslagen in een sessie voor later gebruik echo $ authenticatedToken; echo "\ n"; catch (AuthenticationException $ e) echo $ e-> getMessage (); echo "\ n";
Herinner de authenticatiestroom die aan het begin van dit artikel werd besproken - de bovenstaande code weerspiegelt die reeks.
Het eerste was om de gebruikersreferenties op te halen en een niet-geverifieerd token te maken.
$ unauthenticatedToken = new UsernamePasswordToken ($ gebruikersnaam, $ wachtwoord, 'frontend');
Vervolgens hebben we dat token doorgegeven aan de authenticatiemanager voor validatie.
// authenticate user & get authenticated token $ authenticatedToken = $ authenticationManager-> authenticate ($ unauthenticatedToken);
Wanneer de authenticatiemethode wordt aangeroepen, gebeurt er een heleboel dingen achter de schermen.
Ten eerste selecteert de authenticatiemanager een geschikte authenticatieprovider. In ons geval is het de DatabaseAuthenticationProvider
authenticatieprovider, die zal worden geselecteerd voor authenticatie.
Vervolgens haalt het de gebruiker op door de gebruikersnaam van de DatabaseUserProvider
gebruiker. eindelijk, de checkAuthentication
methode voert de nodige controles uit om het huidige gebruikersverzoek te verifiëren.
Als u de. Wilt testen db_auth.php script, moet u het maken sf_users
tabel in uw MySQL-database.
MAAK TAFEL 'sf_users' ('id' int (11) NOT NULL AUTO_INCREMENT, 'gebruikersnaam' varchar (255) NOT NULL, 'wachtwoord' varchar (255) NOT NULL, 'rollen' enum ('registered', 'moderator', 'admin') DEFAULT NULL, PRIMARY KEY ('id')) MOTOR = InnoDB; INSERT IN 'sf_users' VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');
Ga je gang en voer de db_auth.php script om te zien hoe het gaat. Na succesvolle voltooiing zou u een geverifieerd token moeten ontvangen, zoals getoond in het volgende fragment.
$ php db_auth.php UsernamePasswordToken (user = "admin", authenticated = true, roles = "admin")
Nadat de gebruiker is geverifieerd, kunt u het geverifieerde token in de sessie opslaan voor de volgende aanvragen.
En daarmee hebben we onze eenvoudige verificatiedemo voltooid!
Vandaag hebben we de component Symfony Security bekeken, waarmee u beveiligingsfuncties in uw PHP-toepassingen kunt integreren. We hebben specifiek gesproken over de authenticatiefunctie van de symfony / security-core subcomponent en ik heb je een voorbeeld laten zien van hoe deze functionaliteit kan worden geïmplementeerd in je eigen app.
Voel je vrij om je gedachten te posten met behulp van de onderstaande feed!