Symfony - FOSUserBundle - 登录后写入文件
Symfony - FOSUserBundle - write into file after login
如何在用户登录后将登录写入文件?
我有这个:
<?php
namespace Web\AdminBundle\EventListener;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener {
protected $userManager;
public function __construct(UserManagerInterface $userManager){
$this->userManager = $userManager;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $event->getAuthenticationToken()->getUser();
$myfile = fopen("login.txt", "w");
fwrite($myfile, 'some-text');
fclose($myfile);
}
}
然后:
login_listener:
class: Web\AdminBundle\EventListener\LoginListener
arguments:
userManager: "@fos_user.user_manager"
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
但是这样不行,没有报错。我尝试只调用 die('some-text') 来确保它正常工作,但它什么也没做。
我最近遇到了类似的问题。我必须在每次登录时增加数据库计数。我选择的路线是这样注册订阅者:
class LoginSubscriber implements EventSubscriberInterface
{
public function handleLogin(InteractiveLoginEvent $event)
{
// Inser logic here
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'handleLogin'
];
}
}
然后将订阅者注册为服务,在您的 services.yml(或 xml 中侦听内核事件...):
login.subscriber:
class: Your\Namespace\LoginSubscriber
tags:
- {name: kernel.event_subscriber }
这应该可以解决问题。
编码愉快!
PS:
尽管这种方法在最近的版本中应该可以正常工作,但让我指出我使用的具体版本:
- friendsofsymfony/user-bundle v1.3.6
- symfony/symfony v2.8.7
在 Symfony 3.2 中,您需要以其他方式执行此操作。
//..src/YourBundle/EventListener/LoginListener.php
namespace YourBundle\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
{
/** @var Router */
protected $router;
/** @var TokenStorage */
protected $token;
/** @var EventDispatcherInterface */
protected $dispatcher;
/**
* @param Router $router
* @param TokenStorage $token
* @param EventDispatcherInterface $dispatcher
*/
public function __construct(Router $router, TokenStorage $token, EventDispatcherInterface $dispatcher)
{
$this->router = $router;
$this->token = $token;
$this->dispatcher = $dispatcher;
}
/**
* @param InteractiveLoginEvent $event
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$this->dispatcher->addListener(KernelEvents::RESPONSE, [$this, 'onKernelResponse']);
}
/**
* @param FilterResponseEvent $event
*/
public function onKernelResponse(FilterResponseEvent $event)
{
$user = $this->token->getToken()->getUser(); // here you have your user
//Let's write some thing to the file
$myfile = fopen("login.txt", "w");
fwrite($myfile, 'some-text');
fclose($myfile);
$event->getResponse()->headers->set('Location', $route);
}
`
而且你需要在services.yml
中注册这个eventListener
app.login.listener:
class: YourBundle\EventListener\LoginListener
arguments:
- "@router"
- "@security.token_storage"
- "@event_dispatcher"
tags:
- { name: kernel.event_listener, method: onSecurityInteractiveLogin, event: security.interactive_login}
现在您可以向 onKernelResponse()
方法添加另一个逻辑
如何在用户登录后将登录写入文件?
我有这个:
<?php
namespace Web\AdminBundle\EventListener;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener {
protected $userManager;
public function __construct(UserManagerInterface $userManager){
$this->userManager = $userManager;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$user = $event->getAuthenticationToken()->getUser();
$myfile = fopen("login.txt", "w");
fwrite($myfile, 'some-text');
fclose($myfile);
}
}
然后:
login_listener:
class: Web\AdminBundle\EventListener\LoginListener
arguments:
userManager: "@fos_user.user_manager"
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }
但是这样不行,没有报错。我尝试只调用 die('some-text') 来确保它正常工作,但它什么也没做。
我最近遇到了类似的问题。我必须在每次登录时增加数据库计数。我选择的路线是这样注册订阅者:
class LoginSubscriber implements EventSubscriberInterface
{
public function handleLogin(InteractiveLoginEvent $event)
{
// Inser logic here
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'handleLogin'
];
}
}
然后将订阅者注册为服务,在您的 services.yml(或 xml 中侦听内核事件...):
login.subscriber:
class: Your\Namespace\LoginSubscriber
tags:
- {name: kernel.event_subscriber }
这应该可以解决问题。
编码愉快!
PS:
尽管这种方法在最近的版本中应该可以正常工作,但让我指出我使用的具体版本:
- friendsofsymfony/user-bundle v1.3.6
- symfony/symfony v2.8.7
在 Symfony 3.2 中,您需要以其他方式执行此操作。
//..src/YourBundle/EventListener/LoginListener.php
namespace YourBundle\EventListener;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
{
/** @var Router */
protected $router;
/** @var TokenStorage */
protected $token;
/** @var EventDispatcherInterface */
protected $dispatcher;
/**
* @param Router $router
* @param TokenStorage $token
* @param EventDispatcherInterface $dispatcher
*/
public function __construct(Router $router, TokenStorage $token, EventDispatcherInterface $dispatcher)
{
$this->router = $router;
$this->token = $token;
$this->dispatcher = $dispatcher;
}
/**
* @param InteractiveLoginEvent $event
*/
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
$this->dispatcher->addListener(KernelEvents::RESPONSE, [$this, 'onKernelResponse']);
}
/**
* @param FilterResponseEvent $event
*/
public function onKernelResponse(FilterResponseEvent $event)
{
$user = $this->token->getToken()->getUser(); // here you have your user
//Let's write some thing to the file
$myfile = fopen("login.txt", "w");
fwrite($myfile, 'some-text');
fclose($myfile);
$event->getResponse()->headers->set('Location', $route);
}
`
而且你需要在services.yml
中注册这个eventListener app.login.listener:
class: YourBundle\EventListener\LoginListener
arguments:
- "@router"
- "@security.token_storage"
- "@event_dispatcher"
tags:
- { name: kernel.event_listener, method: onSecurityInteractiveLogin, event: security.interactive_login}
现在您可以向 onKernelResponse()
方法添加另一个逻辑