How to create a custom login event (onLogin) listener using FOSUserBundle in Symfony 3

Normally, the implementation of FOSUserBundle tends to be straight forward and it solves almost all of your requirements. However, there are special tasks, that probably are hard to find in the official documentation or aren't easy to understand. One of these tasks is to do something after an user succesfully start a session (logging into your app) and you need to know when an user do that in order to do something extra (to add parameters in the session according to the email etc).

You could easily replace the "event listener" modifying the code in the bundle (vendor directory), however this is discouraged as it's a bad practice and your changes will be lost on any update, therefore is recommendable to add a login event listener instead.

In this article, you'll learn how to listen specifically for the login event when an user succesfully login to your app.

Implementation

The recommended way, is to create a folder with the name Listeners into your bundle, and create a class with the name LoginListener inside with the following code:

Note: do not forget to change the namespace of the class according to the name of your bundle and location of the class.

<?php

// Change the namespace according to the location of this class in your bundle
namespace myBundle\Listeners;

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();
        
// In order to test if it works, create a file with the name login.txt in the /web path of your project $myfile = fopen("login.txt", "w"); fwrite($myfile, 'onSecurityInteractiveLogin succesfully executed !'); fclose($myfile); // do something else // return new Response(); } }

Now that you have a class that will handle the event, you need to register it as a service in the services.yml file of your project:

services:
    login_listener:
        # path of the previously created class
        class:  myBundle\Listeners\LoginListener
        arguments:
            userManager: "@fos_user.user_manager"
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

Finally, remember to clear the cache (manually or with the command) and proceed to login into your project. As made in this example, a file ("login.txt") will be created in the web directory of your project only for test purposes, feel free to change it for a response or whatever you need to do.

Have fun !

Become a more social person