Symfony 4 : Gestion utilisateurs sans FOSUserBundle v2018 : Chapitre 1

Cet article est écrit en 3 parties : J’avais écrit l’année dernière une série d’articles sur comment gérer les utilisateurs sans FOSUserBundle, il me restait encore à publier « comment modifier son mot de passe et comment faire un « J’ai oublié mon mot de passe ». Vu que les choses ont pas mal bougé en 1 an j’ai décidé de repartir de 0 (mais en reprenant les grandes lignes de l’ancien article). Mon environnement :
  • Linux Mint 19
  • Php 7.2.10
  • MariadB 10.2.18
  • Symfony 4.1.6
On va évidemment commencé par creer le projet : Et tout de suite lancer le serveur : Il suffit maintenant de se rendre sur http://127.0.0.1:8000, et voilà ! Une des nouveautés du bundle maker c’est la possibilité de créer une classe user en ligne de commande ! C’est déjà inclus dans la version que nous avons installé, mais sinon il aurait suffit de faire : Nous allons maintenant passer à la création de la classe : Vous pourrez, sauf si exception, sélectionner tout le temps le choix par défaut. Nous voilà donc avec une classe toute propre contenant quelques champs (email, roles, mot de passe) : Mais ce n’est pas tout, le maker a aussi créer le fichier repository ainsi que le fichier /config/packages/security.yaml Pour ajouter un champ, il suffit d’utiliser le maker entity : Avant de créer la base n’oubliez pas de modifier le fichier env et d’y mettre à jour les identifiants pour accès à votre base de données. On va lancer l’update du schema : On va déjà créer quelques utilisateurs fake, grâce aux fixtures, pour ça il faut ajouter un composant puis la librairie faker : Puis toujours avec ce puissant maker, on va créer la classe que l’on appellera UserFixtures : Ce qui donnera : Il suffit maintenant de créer les fixtures : Ce qui nous donne dans la base 10 magnifiques users : Nous allons maintenant créer le controller, et là aussi on va utiliser le maker : Nous l’appellerons simplement SecurityController : Ce maker créé le controller mais aussi la vue (le fichier twig), on peut donc se rendre sur http://127.0.0.1:8001/security Nous aurons pas besoin de cette route (/security) on pourra la supprimer, on va créer à la place /login qui va se charger d’afficher un formulaire de connexion : Et la le fichier twig security/login.html.twig : Voilà pour cette partie ! Dans la prochaine partie nous rentrerons dans le dur avec la création du formulaire et la connexion de l’utilisateur. Vous pourrez retrouver le code de l’ensemble du projet sur github : https://github.com/gponty/userDemo2018  

19 commentaires

  1. Bonjour
    quand j’essaye de faire la migration doctrine me sort des erreurs:
    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘JSON NOT NULL, passwo
    rd VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C7’ at line 1

    si quelqu’un peut m’aider
    merci

      1. Merci de ta prompte réponse.
        J’ai commencé à créer cette gestion d’utilisateurs, qui me paraît plus simple à gérer que FosUser.
        Tes explications sont claires (bien qu’il manque par exemple cet item sur comment dréer un user…)
        Mon itention est d’arriver à interfacer ça avec EasyAdmin ! Il va falloir que je comprenne comment dire à EasyAdmin comment crypter le mot de passe (avec bcrypt, que j’ai choisi) !

        J’ai commencé à créer cette Command (en utilisant la doc de Symfony) , mais il faut d’abord que je crée un service UserManager. Là ça devient plus dur !

        1. Eheh c’est ce qui est passionnant ! Bon courage !

          Par contre tu n’as pas forcement besoin d’un usermanager.
          Tu peux créer ton user directement dans ta commande, à toi de voir !

  2. Ca peut donner quelque chose comme ça :
    (si tu comptes reeutiliser la création d’user, il vaudrait effectivement mieux passer par un service)
    Tu peux aussi passer l’email, mdp, .. en paramètre de ta commande

    class CreateUserCommand extends Command
    {
    protected static $defaultName = 'create:user';

    private $em;

    private $passwordEncoder;

    public function __construct(
    EntityManagerInterface $em,
    UserPasswordEncoderInterface $passwordEncoder
    )
    {

    $this->em = $em;
    $this->passwordEncoder = $passwordEncoder;

    parent::__construct();

    }

    protected function configure()
    {
    $this->setDescription('Creation d\'un user');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
    $io = new SymfonyStyle($input, $output);

    $user1 = new User();
    $user1->setEmail('g.ponty@dev-web.io');
    $encoded = $this->passwordEncoder->encodePassword($user1, 'passwd');
    $user1->setPassword($encoded);
    $this->em->persist($user1);

    $this->em->flush();

    $io->success('User created.');
    }
    }

  3. Bonjour Guillaume,

    Je voulais d’abord te remercier pour le tuto. Super pratique !

    Seulement, mon cas est différent et je ne sais pas sous quel angle je dois prendre le problème. Explications :

    J’ai une page twig « home » où il est affiché le formulaire de connexion, le formulaire d’inscription et les dernières actualités(le dernier point reste à faire). La vue passe par un contrôleur nommé « HomeController » où il y a une méthode index() où j’y avais commencé à placer le petit bout de code pour l’inscription d’un nouvel utilisateur :

    public function index(Request $request, UserPasswordEncoderInterface $encoder)
    {
    // Formulaire de connexion

    // Création d’un nouvel utilisateur
    $user = new User();

    // Création du formulaire d’inscription
    $form = $this->createForm(UserType::class, $user);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid())
    {
    // Encodage du mot de passe
    $hash = $encoder->encodePassword($user, $user->getPassword());

    $user->setPassword($hash);
    $user->setCreatedAt(new DateTime);

    $this->manager->persist($user);
    $this->manager->flush();

    $this->addFlash(« success », « Votre inscription a bien été prise en compte. »);
    return $this->redirectToRoute(« newsFeed »);
    }

    return $this->render(‘home/home.html.twig’, [
    « formRegister » => $form->createView()
    ]);
    }

    Aurais-tu une idée sur la façon dont je dois appeler la méthode login() dans la méthode index() sans pour autant rentrer en conflit avec le formulaire d’inscription ? Je suis un peu perdu depuis quelques jours avec ça. Est-ce qu’il faut absolument qu’il y ait une nouvelle route pour le login ou puis-je afficher tout de même le login via la page twig « home » ?

    Désolé si je ne parais pas clair mais moi-même je suis dans le flou là. 😀

    1. Bonjour Arnaud,
      Oui tu peux sans problème, il suffit que tu créés 2 formulaires distincts. ($formLogin et $formInscription par exemple)

      Guillaume

      1. Cela veut dire que je dois créer un fichier LoginType et non faire un formulaire à la mano directement dans le fichier home.html.twig ?! Comment vais-je pouvoir faire comprendre à Symfony que ce LoginType est à prendre en compte lors de la connexion ?

        Désolé, je débute encore sous Symfony. J’ai une autre problématique à résoudre, c’est la connexion automatique après s’être inscrit sur le site. De ce côté là, j’ai l’impression que c’est le Guard qui doit faire le boulot avec la possibilité de faire des entrées différentes pour se logger… mais je suis encore loin de tout comprendre.

        Merci beaucoup Guillaume en tout cas pour cette première réponse.

        1. J’ai résolu le problème en séparant les 2 formulaires dans des pages twig différentes. 🙂

          J’avais réussi à tout faire fonctionner mais le problème est que le paramètre « _username » du formulaire de connexion est récupéré dès la requête et donc lorsque je voulais m’inscrire, via le formulaire, sur le site, Symfony me renvoyait une erreur de type « The key « _username » must be a string, « NULL » given. »
          Il me demandait absolument que je lui rentre une valeur même si je n’utilisais pas le formulaire de connexion. Cet attribut prend ses aises et occupe tout l’espace. 😀

          Voilà mon petit retour d’expérience. J’ai l’impression que l’architecture Symfony n’apprécie pas trop le fait qu’il y ait plusieurs formulaires sur une même page…

  4. Bonjour et merci pour ce tuto.

    J’ai deux question qui viennent suite à ça.
    Je travaille sur un projet qui utilise actuellement fosuser et j’aimerai l’enlever pour suivre ton tuto et avoir une meilleure main sur ces fonctions. Cependant je ne trouve pas comment supprimer fosuser pour passer à ça. Ce n’est pas moi qui l’ai intégrer et je ne sais pas quoi enlever.
    Et mon autre questions était si c’était possible de se servir de tous ça avec une base mongodb et donc pas d’entity mais des document ?

    Merci d’avance.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.