Faisons plus simple!
Symfony

Gérer les utilisateurs dans son application Symfony sans le FOSUserBundle

Avec plus de 9 000 téléchargements par jour, le FOSUserBundle fait partie des bundles Symfony les plus populaires. Il est très souvent installé dès le début d’un projet web, pour gérer les utilisateurs (connexion, confirmation de compte…).
Pourtant, dès 2016 Damien Alexandre nous explique dans une conférence qu’il ne faut pas systématiquement l’utiliser, et réfléchir avant de l’ajouter à son projet. Trois années plus tard, la situation un petit peu évolué. Voyons comment faire en 2019, avec Symfony 4.

Ce que le FOSUserBundle apporte, et ce qu’il coûte

Le FOSUserBundle apporte de nombreuses fonctionnalités, voici les principales:

  • une classe User avec les champs généralement utiles et utilisés (email, enabled…), compatible avec Doctrine ORM et ODM ;
  • un formulaire de connexion qui s’intègre avec l’authentification Symfony ;
  • une processus d’inscription pour les utilisateurs, avec si on le souhaite la confirmation de leur e-mail ;
  • une fonctionnalité « mot de passe » oublié complète ;
  • un profil, éditable, pour nos utilisateurs, ainsi que le changement de mot de passe ;
  • des commandes CLI pour certaines opérations (création, changement de mot de passe…) ;
  • des groupes pour organiser les utilisateurs (rarement utilisé).

Toutes ces fonctionnalités ne sont pas toutes autant utilisées. Elles ne sont pas toutes nécessaires dans tous les projets, et surtout, elles demandent souvent pas mal de personnalisation. Je ne connais pas d’applications qui aient gardé le formulaire de login par défaut, ou qui se soient contenté des e-mails (textes) fournis. On a donc au minimum un certain nombre de templates et de traductions à surcharger. Cela devient beaucoup plus lourd si on veut personnaliser le déroulement d’un processus, le système d’évènement n’étant pas toujours assez flexible. On peut se retrouver à devoir ré-copier les contrôleurs pour modifier une ligne, par exemple pour empêcher l’auto-connexion d’un utilisateur après qu’il ait réinitialisé son mot de passe.

Six raisons de ne pas l’utiliser

Au fil des projets j’ai vu différents inconvénients et problèmes arriver. En résumé, voici 6 raisons de se passer du FOSUserBundle:

  • Personnalisation obligatoire au minimum des templates et traductions, et souvent des classes de formulaire.
  • Flexibilité limitée des contrôleurs. Dans de nombreux cas il était nécessaire de recopier du code à défaut de pouvoir surcharger/adapter un point précis.
  • Coût en maintenance de ces personnalisations. La mise à jour avec la montée d’une version à l’autre du bundle devient lourde.
  • Pour la majorité des projets, on embarque des fonctionnalités inutiles (faciles à désactiver, heureusement).
  • Certains fonctionnements sont opaques, par exemple en v2-alpha de nombreuses propriétés redondantes étaient présentes (User::enabled, User::expired, User::expirationDate, User::credentialsExpired…) et n’étaient même pas vérifiées par défaut.
  • Enfin, sur le fond, on s’interdit de choisir des processus plus adaptés et plus proches de notre métier, et souvent plus simples. Un exemple courant est de permettre aux utilisateurs de se connecter avec leur adresse e-mail, et de ne pas avoir du tout de nom d’utilisateur.

Le MakerBundle pour le remplacer plus rapidement

Il est bien sûr possible de coder soi-même tous les fonctionnalités qui nous auraient été utiles. Mais il y un raccourci possible pour gagner du temps. Sous Symfony4, le MakerBundle permet de générer du code pour certains cas courants. Parmi ce qu’il offre, plusieurs commandes vont nous intéresser:

  • make:user permet de générer une entité User (Doctrine) qui contiendra les champs requis par la sécurité ;
  • make:auth form-login créera un formulaire de connexion ;
  • make:registration-form propose un processus d’inscription (formulaire, contrôleur…).

Les trois fonctionnalités « de base » du FOSUserBundle sont donc couvertes. Le code généré est plus simple, littéralement le plus simple possible pour réaliser la fonctionnalité. À l’usage, j’ai trouvé qu’il était plus rapide de personnaliser ce code minimaliste pour rajouter juste ce qu’il fallait au projet, que de chercher dans la configuration et de surcharger. Au final, j’ai l’impression d’avoir moins de code, même! Et plus de problèmes de mise à jour.

Ce qu’il reste à remplacer

Par rapport à la première liste, il manque donc le mot de passe oublié, le profil, et les commandes pour complètement remplacer le bundle.

Pour le mot de passe oublié, je pense qu’il s’agit d’une ajout utile au MakerBundle. J’ai proposé la fonctionnalité et une implémentation dans une Pull Request sur Github. J’espère que la fonctionnalité sera prochainement intégrée et disponible. L’implémentation a bénéficié de nombreux retours et relectures, elle est je pense de meilleure qualité que ce qui était proposé précédemment. Vous pouvez commenter sur la PR pour donner votre avis, soutenir ou pas l’initiative.

Pour le profil et le changement de mot de passe, ils seront à implémenter « à la main ». Il s’agit de relativement peu de code, et dans mon expérience, il fallait toujours surcharger le code fourni par le FOSUserBundle, soit pour des raisons graphiques soit parce que notre User avait plus de champs que ce le formulaire de base permettait d’éditer.

Enfin, il reste les deux commandes qui permettaient à un administrateur ayant accès au serveur de créer un utilisateur ou de changer son mot de passe. Elles étaient pratiques, car le mot de passe est stocké hashé dans la base de donnée, on ne peut pas l’éditer via SQL.
Ces deux commandes sont très simples à ré-implémenter vous-même. Voici 2 exemples commentés, que vous pourrez reprendre dans le répertoire src/App/Command de votre projet:

Bilan

Avec Symfony 4, grâce au MakerBundle, il est facile de faire une application sans embarquer le FOSUserBundle. Cela est devenu mon choix par défaut, j’espère que cela vous permettra de simplifier vos développements 🙂

Visited 145 times, 1 visit(s) today