FOSUserBundle 配置文件上的电子邮件确认编辑
Posted
技术标签:
【中文标题】FOSUserBundle 配置文件上的电子邮件确认编辑【英文标题】:Email confirmation on FOSUserBundle Profile Edit 【发布时间】: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%
有人可以帮助我吗?
【问题讨论】:
【参考方案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 对此进行了介绍。
【讨论】:
以上是关于FOSUserBundle 配置文件上的电子邮件确认编辑的主要内容,如果未能解决你的问题,请参考以下文章
FOSUserBundle 使用电子邮件登录 (Symfony2)
显示配置文件 FOS UserBundle + Sonata UserBundle
FOSUserBundle 上的错误,传递的参数必须是 ObjectManager 的实例