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() 方法添加另一个逻辑