Symfony2密码重置而不覆盖FOSUser

时间:2016-10-14 15:04:15

标签: php symfony

我正在尝试构建一个重置用户密码的表单。我正在使用FOSUserBundle来管理用户,但由于某些架构原因,我不想覆盖FOSUser重置控制器

所以我决定构建自己的类型和控制器来重置密码

PasswordResettingType.php

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('plainPassword', RepeatedType::class, array(
        'type' => PasswordType::class,
        'attr' => ['class' => 'form-group has-feedback'],
        'first_options' => array('label' => false,
            'attr' => ['placeholder' => 'New Password']
            ),
        'second_options' => array('label' => false,
            'attr' => ['placeholder' => 'Repeat Password']),
        'invalid_message' => 'Passwords don't match',
    ));
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'CoreBundle\Entity\User',
        'csrf_token_id' => 'resetting'
    ));
}

重置控制器

/**
 * @Route("/reset/{token}", name="api_resetting_reset")
 */
public function resetAction(Request $request, $token)
{
    $userManager = $this->get('fos_user.user_manager');

    $user = $userManager->findUserByConfirmationToken($token);

    if (null === $user) {
        return $this->render('APIBundle:Resetting:error.html.twig');
    }

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

    $form->handleRequest($request);

    if ($form->isValid()) {
        $user->setConfirmationToken(null);
        $user->setPasswordRequestedAt(null);
        $user->setPlainPassword($form["plainPassword"]->getData());
        $userManager->updateUser($user);

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

    return $this->render('APIBundle:Resetting:reset.html.twig', array(
        'token' => $token,
        'form' => $form->createView()
    ));
}

reset.html.twig

{{ form_start(form) }}

        {% for passwordField in form.plainPassword %}
            <div class="form-group has-feedback">
                {{ form_widget(passwordField, { 'attr': {'class': 'form-control'} }) }}
                <span class="show">show</span>
                {{ form_errors(passwordField) }}
            </div>
        {% endfor %}

    <input type="submit" class="btn" value="Submit" />
{{ form_end(form) }}

但是当我提交表单时,未设置新密码,ConfirmationToken和PasswordRequestedAt不会设置为null。

2 个答案:

答案 0 :(得分:6)

我认为你这样做是错误的。如果您查看FOS用户并仔细阅读文档,您将看到他们正在使用EventListeners执行此操作。

这意味着你可以挂钩并做你的东西。或者,如果你不想这样做,你可以覆盖它并制作自己的。像你正在做的那样做一半是行不通的。例如,您没有检查onResettingResetInitialize事件,该事件检查密码请求是否已过期。

关于最后的答案我认为你真的不需要这样做:

$encoder = $this->container->get('security.password_encoder');
$user->setPassword($encoder->encodePassword($user, $user->getPlainPassword()));

因为这是UserManager-&gt; UpdateUser()

的工作

顺便说一下:你不能从那里调试并放一个转储($ user); exit();并检查输出的内容以及是否正确调用。

Boulzy评论也是正确的:/ reset / {token}与FOS的路径相同。如果使用echo debug_backtrace()调试UpdateUser;你还可以看到从哪里被称为UpdateUser。

答案 1 :(得分:0)

你必须像这样设置新密码:

$encoder = $this->container->get('security.password_encoder');
$user->setPassword($encoder->encodePassword($user, $user->getPlainPassword()));

您可以清除一些数据后:

$user->setConfirmationToken(NULL);
$user->setPasswordRequestedAt(NULL);
$user->setPlainPassword(NULL);