Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encode a password in Symfony 5?

I am trying to encode a password in Symfony and after carefully following the documentation here it still seems like I am doing something wrong.

This is my RegisterController.php:

<?php
    namespace App\Controller;

    use App\Entity\User;
    use App\Form\Type\UserType;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Annotation\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class RegisterController extends AbstractController
{
private $passwordEncoder;

public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
    $this->passwordEncoder = $passwordEncoder;        
}

/**
    * @Route("/register", name="user.register")
    */
public function create(Request $request)
{
    $user = new User();

    $form = $this->createForm(UserType::class, $user);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $user->setPassword( 
            $this->passwordEncoder->encodePassword( $user, $user->getPassword() )
        );

The above returns the following error:

Neither the property "plainPassword" nor one of the methods "getPlainPassword()", "plainPassword()", "isPlainPassword()", "hasPlainPassword()", "__get()" exist and have public access in class "App\Entity\User".

And here is my Register.twig.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Register{% endblock %}</title>
        {# {% block stylesheets %}{% endblock %} #}
    </head>
    <body>
        <div class="container">
            <h2 class="form-signin-heading">Welcome, please register below</h2>
            {{ form(form) }}
        </div>

    </body>
</html>

And finally I have this setup in my security.yaml file:

security:    
   encoders:
        App\Entity\User:
            algorithm: auto

I guess it's something simple that I'm overlooking but I couldn't get it to work. It is my first time with Symfony.

like image 546
goodhand Avatar asked Jan 26 '23 12:01

goodhand


1 Answers

Actually this happen because symfony detect if there is no "plainPassword" property in User entity. The purpose of using this "plainPassword" property is to be a temporary data, so we can encode it. What you need to do is set the "plainPassword" property mapped to be false in you form type.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('plainPassword', RepeatedType::class, array(
            'type'              => PasswordType::class,
            'mapped'            => false,
            'first_options'     => array('label' => 'New password'),
            'second_options'    => array('label' => 'Confirm new password'),
            'invalid_message' => 'The password fields must match.',
        ))
    ;
}

And in your controller encode the "plainPassword" to be encoded "password":

/**
 * @Route("/register", name="app_register")
 */
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response
{
    $user = new User();
    $form = $this->createForm(RegistrationFormType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        // encode the plain password
        $user->setPassword(
            $passwordEncoder->encodePassword(
                $user,
                $form->get('plainPassword')->getData()
            )
        );

        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        // do anything else you need here, like send an email

        return $this->redirectToRoute('any_route');
    }

    return $this->render('registration/register.html.twig', [
        'form' => $form->createView(),
    ]);
}
like image 86
Arnold Richmon Avatar answered Jan 28 '23 10:01

Arnold Richmon