IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Connexion utilisateur (entity_provider) [4.x]


Sujet :

Symfony PHP

  1. #1
    Membre confirmé Avatar de Skunka
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2018
    Messages
    135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 135
    Par défaut Connexion utilisateur (entity_provider)
    Bonsoir,

    pour un projet scolaire je doit gérer la connexion sur un site type e-commerce.
    L'inscription est mise en place avec encodage des mots de passe.
    Lors de la connexion, même si je rentre des identifiants correctes, Symfony me renvoie sur la page de connexion en m'indiquant que les identifiants sont incorrectes.
    En fouillant un peu, je m'apperçois que c'est la vérification du mot de passe dans le LoginFormAuthenticator.php qui retourne false.
    L'utilisateur est bien retrouvé dans la passe mais le dump() dans fonction 'checkCredentials()' me montre que isPasswordValid() retourne false.

    LoginFormAuthneticator:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    <?php
     
    namespace App\Security;
     
    use App\Entity\Utilisateur;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
    use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
    use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
    use Symfony\Component\Security\Core\Security;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Symfony\Component\Security\Csrf\CsrfToken;
    use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
    use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
    use Symfony\Component\Security\Http\Util\TargetPathTrait;
     
    class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
    {
        use TargetPathTrait;
     
        private $entityManager;
        private $urlGenerator;
        private $csrfTokenManager;
        private $passwordEncoder;
     
        public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
        {
            $this->entityManager = $entityManager;
            $this->urlGenerator = $urlGenerator;
            $this->csrfTokenManager = $csrfTokenManager;
            $this->passwordEncoder = $passwordEncoder;
        }
     
        public function supports(Request $request)
        {
            return 'mi22_utilisateur_connexion' === $request->attributes->get('_route')
                && $request->isMethod('POST');
        }
     
        public function getCredentials(Request $request)
        {
            $credentials = [
                'email' => $request->request->get('email'),
                'password' => $request->request->get('password'),
                'csrf_token' => $request->request->get('_csrf_token'),
            ];
            $request->getSession()->set(
                Security::LAST_USERNAME,
                $credentials['email']
            );
     
            return $credentials;
        }
     
        public function getUser($credentials, UserProviderInterface $userProvider)
        {
            $token = new CsrfToken('authenticate', $credentials['csrf_token']);
            if (!$this->csrfTokenManager->isTokenValid($token)) {
                throw new InvalidCsrfTokenException();
            }
     
            $user = $this->entityManager->getRepository(Utilisateur::class)->findOneBy(['email' => $credentials['email']]);
     
            if (!$user) {
                // fail authentication with a custom error
                throw new CustomUserMessageAuthenticationException('Email could not be found.');
            }
     
            return $user;
        }
     
        public function checkCredentials($credentials, UserInterface $user)
        {
            dump($this->passwordEncoder->isPasswordValid($user, $credentials['password']), $user, $credentials['password']);exit; // 'false' , l'objet user, le mdp saisis
            return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
        }
     
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
        {
            if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
                return new RedirectResponse($targetPath);
            }
     
            // For example : return new RedirectResponse($this->urlGenerator->generate('some_route'));
            throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
        }
     
        protected function getLoginUrl()
        {
            return $this->urlGenerator->generate('mi22_utilisateur_connexion');
        }
    }

    Je commence à perdre patiente et je n'ai aucune piste de pourquoi la vérification du mot de passe bloque mon traitement. Je certifie à 100% que les identifiants que je rentre sont correctes, j'en ai recrée 5 pour être sûr.

    Merci d'avance!

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2012
    Messages : 631
    Par défaut
    bonjour,
    comment tu enregistres le mot de passe? via un formulaire ou une fixture?
    quelle est la taille allouée à la colonne password en BD?
    l'absence d'un algo de hachage dans le fichier security.yaml peut aussi la cause de l'erreur.

    Essaie de générer un mot de passe hashé en ligne de commande.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    php bin/console security:encode-password leMotDePasse
    ensuite tu remplaces le mot de passe de la table user de la BD par le hash généré.

  3. #3
    Membre confirmé Avatar de Skunka
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2018
    Messages
    135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 135
    Par défaut
    Bonjour, je me suis servis de la commande suivante pour l'inscription:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    php bin/console make:registration:form
    Qui m'a fourni le controller suivant:

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    class RegistrationController extends AbstractController {
     
        public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $authenticator): Response {
            $user = new Utilisateur();
            $form = $this->createForm(RegistrationFormType::class, $user, [
                'action' => $this->generateUrl('mi22_app_register')
            ]);
            $form->handleRequest($request);
     
     
            if ($form->isSubmitted()) {
                if ($form->isValid()) {
                    // encode the plain password
                    $user->setPassword(
                            $passwordEncoder->encodePassword(
                                    $user,
                                    $user->getPassword()
                            )
                    );
                    $user->setRoles(['ROLE_CLIENT']);
     
                    $entityManager = $this->getDoctrine()->getManager();
                    $entityManager->persist($user);
                    $entityManager->flush();
     
                    // do anything else you need here, like send an email
     
                    return $this->redirectToRoute('mi22_accueil');
                } else {
                    return $this->redirectToRoute('mi22_utilisateur_connexion');
                }
            }
     
            return $this->render('registration/register.html.twig', [
                        'registrationForm' => $form->createView(),
            ]);
        }
     
    }

    Dans la BD, les mots de passe sont bien encodé, je met également mon fichier security.yaml:
    Code yaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    security:
        # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
        providers:
            app_user_provider:
                entity:
                    class: App\Entity\Utilisateur
                    property: email
     
        role_hierarchy:
            ROLE_ADMIN: ROLE_CLIENT
     
        encoders:
            App\Entity\Utilisateur:
                algorithm: bcrypt
                cost: 12
     
        firewalls:
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                anonymous: true
     
                logout:
                    path: utilisateur/deconnexion
                    target: home 
                guard:
                    authenticators:
                        - App\Security\LoginFormAuthenticator
     
                # activate different ways to authenticate
                # https://symfony.com/doc/current/security.html#firewalls-authentication
     
                # https://symfony.com/doc/current/security/impersonating_user.html
                # switch_user: true
     
        # Easy way to control access for large sections of your site
        # Note: Only the *first* access control that matches will be used
        access_control:
            - { path: ^/, roles: [IS_AUTHENTICATED_ANONYMOUSLY, ROLE_USER, ROLE_CLIENT] }
            - { path: ^/utilisaeur/connexion, roles: IS_AUTHENTICATED_ANONYMOUSLY }
            - { path:  ^/commande, roles: [ROLE_USER, ROLE_CLIENT] }
            - { path: ^/back_office, roles: ROLE_ADMIN }

    J'ai généré le mot de passe haché comme tu m'as montré, puis je l'ai assigné à un user de ma BD, la connexion fonctionne avec cet utilisateur (même si la redirection est mauvaise mais c'est une autre histoire).
    Dans la BD, password est défini comme un VARCHAR(255)

    EDIT: je rajoute le lien github du projet concerné => https://github.com/BlueSkunka/Symfony

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2012
    Messages : 631
    Par défaut
    //RegistrationController
    l'attribut $password de l'entité Utilisateur n'est pas mappé avec un champ du formulaire puisqu'il n'existe pas dans ce formulaire.donc à la soumission du formulaire $user->getPassword() renvoie une chaîne vide du coup tu encodes une chaîne vide.
    Dans le formulaire t'as un champ additionnel nommé plainPassword qui n'est pas lié à un attribut de l'entité Utilisateur. c'est ce dernier champ qu'il faut utiliser pour encoder le mot de passe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     //  $form->get('plainPassword')->getData() => récupère le mot de passe en clair envoyé depuis le formulaire
     $user->setPassword(
                  $passwordEncoder->encodePassword(
                   $user,
                    $form->get('plainPassword')->getData()
                   )
       );

  5. #5
    Membre confirmé Avatar de Skunka
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2018
    Messages
    135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2018
    Messages : 135
    Par défaut
    Effectivement le champ n'est pas mappé, erreur bête ^^

    Le problème est résolu, merci beaucoup de ton aide !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/03/2007, 16h26
  2. Connexion utilisateur XP PRO sur domaine WINDOWS 2003 server
    Par barok dans le forum Windows Serveur
    Réponses: 14
    Dernier message: 20/10/2006, 22h27
  3. procedure stocke connexion utilisateur
    Par xman_genius dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 18/09/2006, 15h59
  4. connexion utilisateur !!
    Par topolino dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 30/06/2006, 15h37
  5. Réponses: 2
    Dernier message: 01/12/2005, 16h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo