Imaginons une application quelconque et concentrons nous uniquement sur l’entité comportant les utilisateurs de l’application.
Une entité Person comportant les champs suivants fera l’affaire :
- nom, prénom, mail et téléphone
- username et password
Sommaire
- Notre entité utilisateur
- Cryptage du mot de passe
- Implémentation de l’algorithme bcrypt
- Cryptage du mot de passe dans le formulaire
- Dans notre entité Person
- Dans le controller Person
- Ajout de la connexion
- Dans le controller
- Le formulaire de connexion – template Twig
- Les providers
- Les firewalls
- Testons la connexion
- Pour aller plus loin
- Valider l’unicité du username et mail
- La restriction d’accès
Notre Entité Utilisateur
On ne va pas détailler ici la mise en place des formulaires et autres controllers nous permettant de manipuler les données de notre entité.
voir l’aide symfony sur “make CRUD”
Lorsque nous utilisons notre application, nous sommes “authentifié” en Anonymous.
On peut le voir directement dans le profiler.
Lorsque nous utilisons notre application, nous sommes “authentifié” en Anonymous.
On peut le voir directement dans le profiler.
Nous allons utiliser notre entity Person qui comporte la notion de username et de password pour donner la possibilité aux utilisateurs de s’authentifier.
Pour se faire, nous allons devoir intervenir sur différentes parties de notre code, principalement dans :
- le composant de sécurité pour :
- les firewalls : quels sont les formulaires et route de login et logout
- les providers pour dire où sont les données utilisateurs
- les encoder pour l’algorithme d’encodage à utiliser
- les access_control pour définir les parties de l’application accessible ou non
- l’entité Person
- le controller Person
- ajouter un formulaire de connexion
Cryptage du mot de passe
A ce stade de l’application, le mot de passe en front comme en back ou en bdd n’est pas crypté. Notre première action sera donc de le crypter.
Implémentation de l’algorithme bcrypt
Dans le composant security, il faut ajouter l’encoder à la bonne entité :
-> config\packages\security.yaml
security:
encoders:
App\Entity\Person:
algorithm: bcrypt
Une fois l’encoder ajouté, il faut encoder proprement dit le mot de passe qui est toujours en clair dans notre table.
Cryptage du mot de passe dans le formulaire
En effet, le mot de passe est toujours visible dans notre formulaire
On utilise la class PasswordType que l’on affecte à notre champ Password dans le buider.
(fichier : source/form/PersonType.php)
Avant : ->add(‘password’)
Après : ->add(‘password’, PasswordType::class )
Dans notre entité Person
il faut implémenter la UserInterface à notre entité Person.
Le name space correspondant étant
-> use Symfony\Component\Security\Core\User\UserInterface;
class Person implements UserInterface
{ ../..
Dans la documentation de symfony on voit qu’il est indispensable d’implémenter certaines méthodes dans notre entité pour pouvoir utiliser la UserInterface.
Methods
- getRoles()
- getPassword()
- getSalt()
- getUsername()
- eraseCredentials()
Les méthodes getPassword() et getUsername() existent déjà car nous avons déjà car nous avons les champs username et password dans notre entité Person.
(src/Enity/Person.php)
Ajoutons les lignes suivantes :
public function getRoles() { return [‘ROLE_USER’]; }
public function eraseCredentials() {}
public function getSalt() {}
Dans le controller Person
Quand on appelle la fonction edition ou new, par injection de dépendance on va appeler la class UserPasswordEncoderInterface.
public function new(Request $request, UserPasswordEncoderInterface $encoder): Response
C’est cette classe qui va nous permettre d’encoder le mot de passe.
Dans les fonctions new et edit, il convient d’encoder le mot de passe avec le code ci-dessous avant de flusher l’objet $person
$hash = $encoder->encodePassword($person, $person->getPassword());
$person->setPassword($hash);
Ajout de la connexion
Pour ajouter la notion de connexion, nous allons devoir :
- créer les fonction login et logout dans le controller
- créer un formulaire de connexion (template)
- renseigner, au niveau des providers, l’entité contenant les utilisateurs
- définir dans les firewall : les formulaires et routes à utiliser pour se logout
- préciser les parties de l’application à sécuriser
Dans le controller
Au niveau du controller Person, on va créer la fonction login accessible à partir de la route /login. (ainsi que la déconnexion : /logout )
/**
* @Route(« /connexion », name= »security_login »)
*/
public function login()
{
return $this->render(‘person/login.html.twig’);
}
/**
* @Route(« /logout », name= »security_logout »)
*/
public function logout() { }
Le formulaire de connexion – template Twig
{% extends ‘base.html.twig’ %}
{% block title %}Connexion{% endblock %}
{% block body %}
<h1>Connexion</h1>
<h2>Formulaire de connexion ! ✅</h2>
<form action= »{{ path(‘security_login’) }} » method= »post » >
<input type= »text » id= »username » name= »_username » class= »username » value= » » />
<input type= »password » id= »password » class= »password » name= »_password » />
<button type= »submit » class= »bt-submit » >Connexion</button></form>
{% endblock %}
Les providers
Au niveau des Providers, on va lui dire où sont les utilisateurs, dans quelle entité ils sont.
(config\packages\security.yaml)
providers:
in_memory: { memory: ~ }
in_database:
entity:
class: App\Entity\Person
property: username
Les firewalls
firewalls:
dev: pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
provider: in_database
form_login:
login_path: security_login
check_path: security_login
logout:
path: security_logout
target: person_index
Testons la connexion
La connexion est maintenant opérationnel via le formulaire de connexion :
Une fois connecté, on voit en haut la possibilité de se déconnecter et dans le profiler les informations sur la connexion y sont aussi.