L’authentification utilisateur sous Symfony 4

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

entité utilisateur
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.

profiler symfony

 

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 )

mot de passe
cryptage mot de passe

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 :

  1. créer les fonction login et logout dans le controller
  2. créer un formulaire de connexion (template)
  3. renseigner, au niveau des providers, l’entité contenant les utilisateurs
  4. définir dans les firewall : les formulaires et routes à utiliser pour se logout
  5. 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 :

test de la 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. 

 

se déconnecter
profiler symfony
PrestaShop

Prestashop

Platinium partner

Shoppingfeed

Partner

Google

Premier Partner

Google Suite

Partner

Office 365

Partner

Recherche