【问题标题】:Email confirmation on FOSUserBundle Profile EditFOSUserBundle 配置文件上的电子邮件确认编辑
【发布时间】:2012-04-17 07:30:23
【问题描述】:

我想激活 FOSUserBundle /profile/edit

上的电子邮件确认

/profile/edit 中您已经登录,您可以编辑用户名或输入当前密码的电子邮件地址。 现在,如果用户编辑电子邮件地址,我想发送一封确认电子邮件:)

FOSUserBundle 配置参考中我没有找到执行此操作的设置... https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/configuration_reference.md

这些是我当前的设置:

fos_user:
  db_driver: orm
  firewall_name: main
  user_class: Acme\CoreBundle\Entity\User
  registration:
    confirmation: { enabled: true }
  from_email:
    address: noreply@%domain%
    sender_name: %site_name% Staff
  resetting:
    token_ttl: %reset_password_ttl%

有人可以帮助我吗?

【问题讨论】:

    标签: php symfony fosuserbundle


    【解决方案1】:

    使用新的 FOSUserBundle 事件(FOS 2.0 功能),您可以创建处理电子邮件更改的ChangeProfileListener

    想法:使用与注册过程相同的逻辑:禁用我们的用户,向他发送令牌(并为我们的案例注销他)。

    有两件事要做:

    • 创建事件订阅者
    • 覆盖 mail.txt.twig 以将“注册”消息替换为中性的“电子邮件确认”消息。

    这是我的监听器,别忘了替换命名空间。

    EventListener/ChangeProfileListener.php:

    <?php
    
    // src/Fuz/HomeBundle/EventListener/ChangeProfileListener.php
    
    namespace Fuz\HomeBundle\EventListener;
    
    use FOS\UserBundle\FOSUserEvents;
    use FOS\UserBundle\Event\GetResponseUserEvent;
    use FOS\UserBundle\Event\FormEvent;
    use FOS\UserBundle\Mailer\MailerInterface;
    use FOS\UserBundle\Util\TokenGeneratorInterface;
    use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Session\SessionInterface;
    use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
    
    class ChangeProfileListener implements EventSubscriberInterface
    {
    
        private $mailer;
        private $tokenGenerator;
        private $router;
        private $session;
        private $tokenStorage;
    
        public function __construct(MailerInterface $mailer, TokenGeneratorInterface $tokenGenerator,
           UrlGeneratorInterface $router, SessionInterface $session, TokenStorageInterface $tokenStorage)
        {
            $this->mailer = $mailer;
            $this->tokenGenerator = $tokenGenerator;
            $this->router = $router;
            $this->session = $session;
            $this->tokenStorage = $tokenStorage;
        }
    
        public static function getSubscribedEvents()
        {
            return array(
                    FOSUserEvents::PROFILE_EDIT_INITIALIZE => 'onProfileEditInitialize',
                    FOSUserEvents::PROFILE_EDIT_SUCCESS => 'onProfileEditSuccess',
            );
        }
    
        public function onProfileEditInitialize(GetResponseUserEvent $event)
        {
            // required, because when Success's event is called, session already contains new email
            $this->email = $event->getUser()->getEmail();
        }
    
        public function onProfileEditSuccess(FormEvent $event)
        {
            $user = $event->getForm()->getData();
            if ($user->getEmail() !== $this->email)
            {
                // disable user
                $user->setEnabled(false);
    
                // send confirmation token to new email
                $user->setConfirmationToken($this->tokenGenerator->generateToken());
                $this->mailer->sendConfirmationEmailMessage($user);
    
                // force user to log-out
                $this->tokenStorage->setToken();
    
                // redirect user to check email page
                $this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
                $url = $this->router->generate('fos_user_registration_check_email');
                $event->setResponse(new RedirectResponse($url));
            }
        }
    
    }
    

    services.yml:

    parameters:
        fuz_home.email_change.listener.class: Fuz\HomeBundle\EventListener\ChangeProfileListener
    
    services:
          fuz_home.email_change.listener:
              class: %fuz_home.email_change.listener.class%
              arguments: ['@fos_user.mailer', '@fos_user.util.token_generator', '@router', '@session', '@security.token_storage']
              tags:
                - { name: kernel.event_subscriber }
    

    关于覆盖邮件模板,也就是创建 app/Resources/FOSUserBundle/views/Registration/email.txt.twig 并放入,例如:

    {% block subject %}
    Email Confirmation
    {% endblock %}
    
    {% block body_text %}
    
    Welcome to example.com, {{ user.username }}!                                                
    
    To confirm your email, please follow this link:                                                                    
    {{ confirmationUrl }}
    
    You will be able to log-in using the username or email you given:                                        
    
    Username : {{ user.username }}                                                                                                         
    Email    : {{ user.email }}                                                                                                 
    
    If you received this e-mail in error just ignore this message. No further actions are required from you.                  
    
    
    
                                                         *****                                                           
    
                                                     See you soon!
    {% endblock %}
    

    【讨论】:

    • 这个解决方案确实有一个问题,当用户更改电子邮件时,数据库会更新。如果电子邮件错误,他们如何重新进入系统?将新电子邮件存储在不同的字段中不是更好吗?
    【解决方案2】:

    发送确认邮件的功能只存在于

    RegistrationFormHandler->onSucces
    

    该配置变量在哪里被传递和检查。配置文件/编辑中不存在类似的功能:

    ProfileFormHandler->onSuccess.
    

    因此,您需要覆盖 FOS ProfileFormHandler 并自己添加此功能。 FOSUserBundle documentation: Overriding Forms 对此进行了介绍。

    【讨论】:

      猜你喜欢
      • 2018-01-11
      • 1970-01-01
      • 2018-03-21
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多