Dans cet article, vous allez apprendre à configurer l'authentification d'utilisateur en PHP à l'aide du composant Symfony Security. En plus de l'authentification, je vais vous montrer comment utiliser son autorisation basée sur les rôles, que vous pouvez étendre selon vos besoins..
Le composant de sécurité Symfony vous permet de configurer des fonctionnalités de sécurité telles que l’authentification, l’autorisation basée sur les rôles, les jetons CSRF, etc., très facilement. En fait, il est divisé en quatre sous-composants que vous pouvez choisir en fonction de vos besoins..
Le composant Sécurité comprend les sous-composants suivants:
Dans cet article, nous allons explorer la fonctionnalité d’authentification fournie par le symfony / security-core composant.
Comme d'habitude, nous commencerons par les instructions d'installation et de configuration, puis nous explorerons quelques exemples concrets pour illustrer les concepts clés..
Dans cette section, nous allons installer le composant Symfony Security. Je suppose que vous avez déjà installé Composer sur votre système. Nous en aurons besoin pour installer le composant de sécurité disponible sur Packagist..
Alors allez-y et installez le composant de sécurité en utilisant la commande suivante.
$ composer a besoin de symfony / security
Nous allons charger les utilisateurs de la base de données MySQL dans notre exemple, nous aurons donc également besoin d'une couche d'abstraction de base de données. Installons l'une des couches d'abstraction de base de données les plus populaires: Doctrine DBAL.
$ compositeur nécessite doctrine / dbal
Cela aurait dû créer le composer.json fichier, qui devrait ressembler à ceci:
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7"
Modifions le composer.json fichier à ressembler au suivant.
"require": "symfony / security": "^ 4.1", "doctrine / dbal": "^ 2.7", "autoload": "psr-4": "Sfauth \\": "src" , "classmap": ["src"]
Comme nous avons ajouté un nouveau classmap
entrée, mettons à jour l'autoloader du compositeur en exécutant la commande suivante.
$ compositeur dump -o
Maintenant, vous pouvez utiliser le Sfauth
espace de noms pour charger automatiquement les classes sous la src annuaire.
C'est donc la partie installation, mais comment êtes-vous censé l'utiliser? En fait, il s’agit simplement d’inclure le autoload.php fichier créé par Composer dans votre application, comme indiqué dans l'extrait suivant.
Commençons par le flux d’authentification habituel fourni par le composant Symfony Security..
Interface utilisateur
interface.Dans notre exemple, nous allons faire correspondre les informations d'identification de l'utilisateur avec la base de données MySQL. Nous devrons donc créer le fournisseur d'utilisateurs de la base de données. Nous allons également créer le fournisseur d'authentification de base de données qui gère la logique d'authentification. Et enfin, nous allons créer la classe User, qui implémente le Interface utilisateur
interface.
Dans cette section, nous allons créer la classe User qui représente l'entité utilisateur dans le processus d'authentification..
Allez-y et créez le src / User / User.php fichier avec le contenu suivant.
nom d'utilisateur = $ nom d'utilisateur; $ this-> mot de passe = $ mot de passe; $ this-> rôles = $ rôles; fonction publique getUsername () return $ this-> nom d'utilisateur; fonction publique getPassword () return $ this-> mot de passe; fonction publique getRoles () return explode (",", $ this-> rôles); fonction publique getSalt () return "; fonction publique eraseCredentials ()
L’important est que la classe User doit implémenter la sécurité Symfony. Interface utilisateur
interface. En dehors de cela, il n'y a rien d'extraordinaire ici.
Il incombe au fournisseur d’utilisateurs de charger les utilisateurs à partir du back-end. Dans cette section, nous allons créer le fournisseur d’utilisateurs de base de données, qui charge l’utilisateur à partir de la base de données MySQL..
Créons le src / User / DatabaseUserProvider.php fichier avec le contenu suivant.
connexion = $ connexion; fonction publique loadUserByUsername ($ username) return $ this-> getUser ($ username); fonction privée getUser ($ nom_utilisateur) $ sql = "SELECT * FROM sf_users WHERE nom_utilisateur =: nom"; $ stmt = $ this-> connection-> prepare ($ sql); $ stmt-> bindValue ("name", $ username); $ stmt-> execute (); $ row = $ stmt-> fetch (); if (! $ row ['nomutilisateur'])) $ exception = new UsernameNotFoundException (sprintf ('Nomutilisateur "% s" introuvable dans la base de données.', $ row ['nomutilisateur'])); $ exception-> setUsername ($ username); jeter $ exception; else retour nouvel utilisateur ($ row ['nomutilisateur'], $ row ['mot de passe'], $ row ['rôles'])); public function refreshUser (UserInterface $ user) if (! $ $ instance d'utilisateur de User) lève une nouvelle exception UnsupportedUserException (sprintf ('Les instances de "% s" ne sont pas prises en charge.', get_class ($ user)); return $ this-> getUser ($ user-> getUsername ()); fonction publique supportsClass ($ class) return 'Sfauth \ User \ User' === $ class;
Le fournisseur de l’utilisateur doit implémenter le UserProviderInterface
interface. Nous utilisons la doctrine DBAL pour effectuer les opérations liées à la base de données. Comme nous avons mis en place le UserProviderInterface
interface, nous devons mettre en œuvre le loadUserByUsername
, rafraîchirUtilisateur
, et supportClass
les méthodes.
le loadUserByUsername
méthode devrait charger l'utilisateur par le nom d'utilisateur, et cela se fait dans le getUser
méthode. Si l'utilisateur est trouvé, nous retournons le correspondant Sfauth \ Utilisateur \ Utilisateur
objet, qui implémente le Interface utilisateur
interface.
D'autre part, le rafraîchirUtilisateur
met à jour la méthode fournie Utilisateur
objet en récupérant les dernières informations de la base de données.
Et finalement, le supportClass
méthode vérifie si le DatabaseUserProvider
fournisseur prend en charge la classe d'utilisateurs fournie.
Enfin, nous devons implémenter le fournisseur d'authentification d'utilisateur, qui définit la logique d'authentification, à savoir comment un utilisateur est authentifié. Dans notre cas, nous devons faire correspondre les informations d'identification de l'utilisateur à la base de données MySQL. Nous devons donc définir la logique d'authentification en conséquence..
Allez-y et créez le src / User / DatabaseAuthenticationProvider.php fichier avec le contenu suivant.
userProvider = $ userProvider; fonction protégée retrieveUser ($ username, usernamePasswordToken $ token) $ user = $ token-> getUser (); if ($ user instanceof UserInterface) return $ user; try $ user = $ this-> userProvider-> loadUserByUsername ($ username); if (! $ user instanceof UserInterface) lance une nouvelle AuthenticationServiceException ('Le fournisseur de l'utilisateur doit renvoyer un objet UserInterface.'); return $ user; catch (UsernameNotFoundException $ e) $ e-> setUsername ($ username); jeter $ e; catch (\ Exception $ e) $ e = new AuthenticationServiceException ($ e-> getMessage (), 0, $ e); $ e-> setToken ($ token); jeter $ e; Fonction protégée checkAuthentication (UserInterface $ user, UsernamePasswordToken $ token) $ currentUser = $ token-> getUser (); if ($ currentUser instanceof UserInterface) if ($ currentUser-> getPassword ()! == $ user-> getPassword ()) jette new AuthenticationException ('Les informations d'identification ont été modifiées à partir d'une autre session.'); else $ password = $ token-> getCredentials (); if (empty ($ password)) lance la nouvelle AuthenticationException ('Le mot de passe ne peut pas être vide.'); if ($ user-> getPassword ()! = md5 ($ password)) lance la nouvelle AuthenticationException ('Le mot de passe est invalide.');
le DatabaseAuthenticationProvider
Le fournisseur d'authentification étend la UserAuthenticationProvider
classe abstraite. Par conséquent, nous devons mettre en œuvre le récupérerUser
et checkAuthentication
méthodes abstraites.
Le métier de récupérerUser
méthode consiste à charger l'utilisateur à partir du fournisseur d'utilisateur correspondant. Dans notre cas, il utilisera le DatabaseUserProvider
fournisseur pour charger l'utilisateur depuis la base de données MySQL.
D'autre part, le checkAuthentication
méthode effectue les vérifications nécessaires afin d’authentifier l’utilisateur actuel. Veuillez noter que j'ai utilisé la méthode MD5 pour le cryptage de mot de passe. Bien sûr, vous devez utiliser des méthodes de cryptage plus sécurisées pour stocker les mots de passe des utilisateurs..
Jusqu'à présent, nous avons créé tous les éléments nécessaires à l'authentification. Dans cette section, nous verrons comment tout mettre en place pour configurer la fonctionnalité d’authentification..
Allez-y et créez le db_auth.php fichier et le remplir avec le contenu suivant.
'mysql: // USERNAME: PASSWORD @ HOSTNAME / DATABASE_NAME'), new \ Doctrine \ DBAL \ Configuration ()); // initialiser notre fournisseur d'utilisateurs de base de données personnalisé $ userProvider = new DatabaseUserProvider ($ doctrineConnection); // nous utiliserons UserChecker par défaut, il est utilisé pour vérifier les vérifications supplémentaires comme le verrouillage de compte / expiré, etc. // vous pouvez implémenter les vôtres en implémentant l'interface UserCheckerInterface $ userChecker = new UserChecker (); // initie notre fournisseur d'authentification de base de données personnalisé $ dbProvider = new DatabaseAuthenticationProvider ($ userProvider, $ userChecker, 'frontend'); // init gestionnaire de fournisseur d'authentification $ authenticationManager = new AuthenticationProviderManager (array ($ dbProvider)); try // init un / pw, vous les récupérez généralement à partir de la variable $ _POST, soumise par l'utilisateur final $ username = 'admin'; $ password = 'admin'; // récupère le jeton non authentifié $ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend'); // authentifie l'utilisateur et obtient le jeton authentifié $ authentifiéToken = $ authentificationManager-> authentifié ($ unauthenticatedToken); // nous avons le jeton authentifié (l'utilisateur est connecté maintenant), il peut être stocké dans une session pour une utilisation ultérieure echo $ authentifiéToken; echo "\ n"; catch (AuthenticationException $ e) echo $ e-> getMessage (); echo "\ n";
Rappelez-vous le flux d'authentification qui a été discuté au début de cet article - le code ci-dessus reflète cette séquence.
La première chose à faire était de récupérer les informations d'identification de l'utilisateur et de créer un jeton non authentifié..
$ unauthenticatedToken = new UsernamePasswordToken ($ username, $ password, 'frontend');
Ensuite, nous avons transmis ce jeton au gestionnaire d'authentification pour validation..
// authentifie l'utilisateur et obtient le jeton authentifié $ authentifiéToken = $ authentificationManager-> authentifié ($ unauthenticatedToken);
Lorsque la méthode authenticate est appelée, beaucoup de choses se passent dans les coulisses.
Tout d'abord, le gestionnaire d'authentification sélectionne un fournisseur d'authentification approprié. Dans notre cas, c'est le DatabaseAuthenticationProvider
fournisseur d'authentification, qui sera sélectionné pour l'authentification.
Ensuite, il récupère l’utilisateur par le nom d’utilisateur du DatabaseUserProvider
fournisseur d'utilisateur. Finalement, le checkAuthentication
méthode effectue les vérifications nécessaires pour authentifier la demande de l'utilisateur actuel.
Si vous souhaitez tester le db_auth.php script, vous aurez besoin de créer le sf_users
table dans votre base de données MySQL.
CREATE TABLE 'sf_users' ('id' int (11) NON NULL AUTO_INCREMENT, 'nom d'utilisateur' varchar (255) NON NULL, 'mot de passe' varchar (255) NON NULL, 'rôles' enum ('enregistré', 'modérateur', ' 'admin') DEFAULT NULL, PRIMARY KEY ('id')) ENGINE = InnoDB; INSERT INTO 'sf_users' VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin');
Allez-y et lancez le db_auth.php script pour voir comment ça se passe. En cas de réussite, vous devriez recevoir un jeton authentifié, comme indiqué dans l'extrait de code suivant..
$ php db_auth.php UsernamePasswordToken (utilisateur = "admin", authentifié = true, roles = "admin")
Une fois l'utilisateur authentifié, vous pouvez stocker le jeton authentifié dans la session pour les demandes suivantes..
Et avec cela, nous avons terminé notre démonstration d'authentification simple!
Aujourd'hui, nous avons examiné le composant Symfony Security, qui vous permet d'intégrer des fonctionnalités de sécurité dans vos applications PHP. Plus précisément, nous avons discuté de la fonctionnalité d'authentification fournie par le sous-composant symfony / security-core, et je vous ai montré un exemple de la manière dont cette fonctionnalité peut être implémentée dans votre propre application..
N'hésitez pas à poster vos pensées en utilisant le flux ci-dessous!