Symfony-如何使用$ event-> getPasswordToken()工作?

时间:2018-12-26 16:11:04

标签: php symfony symfony-3.4

我正在尝试为已经制作好的Symfony 3.4应用程序实施密码重置功能。现在,我需要检查通过电子邮件发送的用户令牌,并将其与数据库中保存的令牌进行比较。我似乎无法在代码中使用$ event-> getPasswordToken()...

  

控制器“ AppBundle \ Controller \ ResettingController :: resetting()”要求您为“ $ event”参数提供一个值。该参数可以为空,并且没有提供空值,没有提供默认值,或者因为此参数之后有一个非可选参数。

<?php 

namespace AppBundle\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Form\FormErrorIterator;
use AppBundle\Entity\User;
use AppBundle\Form\ResettingType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Twig\Environment;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use AppBundle\Services\Mailer;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use CoopTilleuls\ForgotPasswordBundle\Event\ForgotPasswordEvent;
use CoopTilleuls\ForgotPasswordBundle\Entity\AbstractPasswordToken;
use AppBundle\Event;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

/**
 * @Route("/password-change")
 */
class ResettingController extends Controller
{

    /**
     * @Route("/{id}/{token}", name="resetting")
     * @param ResettingController $event
     */
    public function resetting(ForgotPasswordEvent $event, User $user, $token, Request $request)
    {

        die($token." -> ".$event->getPasswordToken());

        if ($user->getToken() === null || $token !== $user->getToken())
        {
            $request->getSession()->getFlashBag()->add('error', "Lien d'accès invalide");
            return $this->redirectToRoute('security_login');
        }

        $form = $this->createFormBuilder()
                                            ->add('_password1', PasswordType::class, array("label"=>"Entrez un nouveau mot de passe:"))
                                            ->add('_password2', PasswordType::class, array("label"=>"Retapez ce même mot de passe:"))
                                            ->getForm();
        $form->handleRequest($request);

        if($form->isSubmitted() && $form->isValid())
        {
            $encoder = $this->get('security.password_encoder');
            $password = $encoder->encodePassword($user, $user->getPlainPassword());
            $user->setPassword($password);
            // réinitialisation du token à null pour qu'il ne soit plus réutilisable
            $user->setPasswordToken(null);
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();
            $request->getSession()->getFlashBag()->add('success', "Votre mot de passe a été modifié.");
            return $this->redirectToRoute('security_login');
        } 

        return $this->render('Security/change-password.html.twig', [
            'form' => $form->createView(),
            'title' => "Changement de mot de passe",
            'error' => $form->getErrors()
        ]);

    }
}

(对于标头中的所有用法,我感到很抱歉...我进行了很多操作系统测试,以使代码正常工作,并且不确定哪一个需要保留,哈尔·高纳稍后再看)

该模具在URL中返回令牌,但在数据库中的令牌上为空,并返回该错误。我正在尝试使$ event工作,以便使用getPasswordToken()函数。

该功能当前在以下控制器中与成功一起使用:

<?php

namespace AppBundle\Event;
use CoopTilleuls\ForgotPasswordBundle\Event\ForgotPasswordEvent;

class ForgotPasswordEventListener
{

    private $templating;
    private $mailer;
    private $manager;

    public function __construct(\Twig_Environment $templating, \Swift_Mailer $mailer, \Doctrine\ORM\EntityManager $manager)
    {
        $this->templating = $templating;
        $this->mailer = $mailer;
        $this->manager=$manager;
    }

    /**
     * @param ForgotPasswordEvent $event
     */
    public function onCreateToken(ForgotPasswordEvent $event)
    {
        $passwordToken = $event->getPasswordToken();
        $user = $passwordToken->getUser();

        $swiftMessage = new \Swift_Message(
            'Reset of your password',
            $this->templating->render(
             'Security/forgot-password.html.twig',
                [
                    'reset_password_url' => sprintf('http://www.quebecenreseau.servlinks.com/intranet/password-change/%s/%s', $user->getId(), $passwordToken->getToken()),
                ]
            )
        );

        $swiftMessage->setFrom('patrick.simard@servlinks.com');
        $swiftMessage->setTo($user->getEmail());
        $swiftMessage->setContentType('text/html');
        if (0 === $this->mailer->send($swiftMessage)) {
            throw new \RuntimeException('Unable to send email');
        }
    }

/*
        public function onUpdatePassword(ForgotPasswordEvent $event)
        {
            $passwordToken = $event->getPasswordToken();
            $user = $passwordToken->getUser();
            $user->setPlainPassword($event->getPassword());
            $this->manager->persist($user);
        }
*/

}

这是我的服务文件:

# Learn more about services, parameters and containers at
# http://symfony.com/doc/current/book/service_container.html

parameters:
#    parameter_name: value

services:
    app.security.login_form_authenticator:
        class: AppBundle\Security\LoginFormAuthenticator
        autowire: true

    app.doctrine.hash_password_listener:
        class: AppBundle\Doctrine\HashPasswordListener
        autowire: true
        tags:
            - { name: doctrine.event_subscriber }

    app.locale_listener:
        class: AppBundle\EventListener\LocaleListener
        arguments: ['%kernel.default_locale%','@security.authorization_checker']
        tags:
            - { name: kernel.event_subscriber }

    app.login_listener:
        class: AppBundle\EventListener\LoginListener
        arguments: ['@session']
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }

    app.mailer:
        class: AppBundle\Service\Mailer
        arguments: ['@mailer','@templating']

    app.utility:
        class: AppBundle\Service\Utility
        arguments: ['@doctrine.orm.default_entity_manager']

    app.filemanager:
        class: AppBundle\Service\FileManager

    app.twig_extension:
        class: AppBundle\Twig\AppExtension
        arguments: ['@translator.default','@request_stack']
        public: false
        tags:
            - { name: twig.extension }       
    app.sae:
        class: AppBundle\Service\Entity\Sae
        arguments: ['@doctrine.orm.default_entity_manager']

    app.document:
        class: AppBundle\Service\Entity\Document
        arguments: ['@doctrine.orm.default_entity_manager']

    app.professional:
        class: AppBundle\Service\Entity\Professional
        arguments: ['@doctrine.orm.default_entity_manager']

    app.article:
        class: AppBundle\Service\Entity\Article
        arguments: ['@doctrine.orm.default_entity_manager']

    app.course:
        class: AppBundle\Service\Entity\Course
        arguments: ['@doctrine.orm.default_entity_manager']

    app.useraddon:
        class: AppBundle\Service\Entity\UserAddon
        arguments: ['@doctrine.orm.default_entity_manager']

    app.jwt_token_authenticator:
        class: AppBundle\Security\JwtAuthenticator
        arguments: ['@doctrine.orm.entity_manager', '@lexik_jwt_authentication.encoder']

    app.listener.forgot_password:
        class: AppBundle\Event\ForgotPasswordEventListener      
        arguments:
            - "@twig"
            - "@mailer"
            - "@doctrine.orm.entity_manager"
        tags:
            - { name: kernel.event_listener, event: coop_tilleuls_forgot_password.create_token, method: onCreateToken}
            - { name: templating.helper, alias: templating, event: coop_tilleuls_forgot_password.create_token, method: onCreateToken}
            - { name: kernel.event_listener, event: coop_tilleuls_forgot_password.update_password, method: onUpdatePassword }

    app.ResettingController:
        class: AppBundle\Controller\ResettingController
        tags:
            - { name: kernel.event_listener, event: app.ResettingController }


    kernel.event_listener.json_request_transformer:
        class: Qandidate\Common\Symfony\HttpKernel\EventListener\JsonRequestTransformerListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 100 }

令牌保存在一个单独的表中,如下所示: enter image description here

我需要将保存令牌与URL中的令牌进行比较,然后在用户提交新密码后从数据库中删除令牌。

到目前为止,我使用其他控制器的功能的所有尝试都失败了。

1 个答案:

答案 0 :(得分:0)

PasswordToken必须是实体用户的属性。所以您可以随时检查