如何在 Symfony 5 中对密码进行编码?

How to encode a password in Symfony 5?

我正在尝试在 Symfony 中对密码进行编码,在仔细按照文档 here 进行操作后,我似乎仍然做错了什么。

这是我的 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() )
        );

以上returns错误如下:

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

这是我的 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>

最后,我的 security.yaml 文件中有了这个设置:

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

我想我忽略了一些简单的事情,但我无法让它工作。这是我第一次 Symfony.

问题在别处。

如果您调用 "plainPassword" 方法,请检查您的树枝或您的表单,该方法不存在,并将其替换为 "password"。

错误似乎在 twig 文件中。您尝试显示 $plainPassword 成员,但它很可能未在实体上定义(在我开始使用 symfony 的过程中,经常会出现此错误)。尝试将其删除,然后检查错误。

密码的编码请看this url, as it explains how the passwords are encrypted in the security.yml file. You need to define the class that will be encoded, the algorithm can be changed for a custom one, that you can build and for this, please check this URL

编码没有那么复杂,但错误与编码无关,所以请试试这个并更新post。

所以,我发现错误唉!我在 UserType.php:

中设置了字段 plainPassword
class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('firstname', TextType::class)
        ->add('lastname', TextType::class)
        ->add('email', EmailType::class)
        ->add('birthdate', DateType::class)
        ->add('plainPassword', RepeatedType::class, array(
            'type' => PasswordType::class,
            'first_options'  => array('label' => 'Password'),
            'second_options' => array('label' => 'Repeat Password'),
        ))
        ->add('save', SubmitType::class, ['label' => 'Register']);
    }
...

将其更改为 password 就像我在 User 实体中所做的那样可以更正错误。

谢谢大家的帮助。

实际上发生这种情况是因为 symfony 检测用户实体中是否没有“plainPassword”属性。使用这个“plainPassword”属性的目的是作为一个临时数据,所以我们可以对其进行编码。您需要做的是在您的表单类型中将“plainPassword”属性 mapped 设置为 false

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.',
        ))
    ;
}

并在您的控制器中将“plainPassword”编码为“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(),
    ]);
}