Login event listener in Symfony2

Login event listener in Symfony2

So you have a Symfony2 project under construction. Login works. Now you want to execute some code right after the user successfully logs in.

The solution: Make a custom event listener.

An event listener is actually a service with a proper tag associated with it. So first step is to register the listener. The configuration file shown corresponds to the listener in file Acme/UserBundle/Listener/LoginListener.php. You can read more about services here.

In services.yml:

Let’s go through the configuration.

class defines the listener class.

With arguments we inject services that this listener depends on. In this case the security.context service for retrieving the User object and doctrine service for EntityManager.

tags is important. Every listener must be tagged with kernel.event_listener and must specify it’s event. For successful login that event is security.interactive_login. You can also specify the optional method tag.

Ok, our listener is registered. Let’s create it.

The above code should be pretty self-explanatory. The only required method is onSecurityInteractiveLogin(InteractiveLoginEvent $event). You do not need the other stuff, but you probably will if you want to modify the User object, or something else in the DB.

22 Responses so far.

  1. Ruben de Vries says:

    Thanks for the snippets, really helped me out a lot :)

  2. This is MISTAKEN – you need to put the ->getUser() in the onSecurityInteractiveLogin function. Otherwise, the user isn’t logged in yet!

  3. Dattaya says:

    I’ve got user object this way: $user = $event->getAuthenticationToken()->getUser();
    (sf2.0.9)

  4. bnlab says:

    thanks for this simple but powerful tuti!

  5. Flo says:

    Thanks for the snippets.

    But how to get the container to do this:

    $this->container->get(‘request’)->getSession->setFlashes(‘message’, ………..);

    Thanks

  6. Metod says:

    You should add a new dependency to the service: @session

    Then you can get it in the constructor and do what you need. :)

  7. Paolo says:

    Great tutorial

    Is possible to do the same with logout action ?

    Thanks again

  8. Thierry says:

    Hi,
    With sf2.1, i think one use must be updated :
    use Doctrine\Bundle\DoctrineBundle\Registry as Doctrine;

    Thanks for the article.

  9. Metod says:

    You are correct. Thanks, will update. :)

  10. This is the first time I encounter this security.interactive_login event, is this documented somewhere? Or is there some place in the docs where all the events are listed?

  11. Metod says:

    I haven’t found a page where all events would be documented yet. I think I found this event in the source code of the Security component.

    https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/SecurityEvents.php

    You can find other events in similar files in other components, for example:

    https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/KernelEvents.php

    Hope this helps ;)

  12. Guillaume says:

    Thanks for the tip. But what if user logs in with a cookie. How can we perform actions in that case ?

  13. Metod says:

    You can check out this answer: http://stackoverflow.com/a/11431221/268592

    Basically the same event gets triggered on remember_me and on usual login. You need to just inspect the cookie. I will add an example later.

  14. Metod says:

    Actually you don’t need to inspect the cookie. I’ve refined the gist above and added the remember me check aswell.

  15. George says:

    Creating a Login and SignUp application using symfony2 and twitter bootstrap in 30min
    5 video to show hot to setup a login and signup application from scratch..
    http://youtu.be/AvLk3i2CBgw
    http://youtu.be/seztFo5j7H4
    http://youtu.be/hzURtNJUQb4
    http://youtu.be/Uh0a7m2XxLU
    http://youtu.be/sE7f5k9NZ6A

  16. gondo says:

    hi
    using your code im getting “The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.”
    im using symfony2.3.2 and FOSUser dev-master 6fc28e4 (from 18.7.13)
    for now i’ve solved this by adding this into onSecurityInteractiveLogin:
    $token = $event->getAuthenticationToken();
    $this->securityContext->setToken($token);

    the question is, is this correct/secure?

  17. Sergio says:

    You Rock man!

    Thanks very much!

  18. Benoît Wery says:

    Short and usefull : thanks you !
    I’ve implemented a last ip remember in few minutes, thanks to your post

  19. Panos says:

    Thank you for sharing