Search code examples
phpsymfonyjwtsymfony-security

Symfony authentication event that fires only once?


I want to log logins.

But both InteractiveLogin and AuthenticationSuccess events fire on each request (because we use JWT to authenticate, which is passed as a header with every request), and the frontend does the redirection after a successful /api/login call, there is no way for me to know, whether the user just logged in.

How would you approach this?


Solution

  • If you are using a stateless firewall, as is the case when using JWT, the classic InteractiveLogin and AuthenticationSuccess are useless for this.

    What you want to log is when the token is actually generated.

    If you are using lexik/LexikJWTAuthenticationBundle, you could listen for a JWTCreatedEvent event to register that a user logged in.

    class JwtCreatedSubscriber implements EventSubscriberInterface
    {
     public static function getSubscribedEvents(): array
        {
            return [
                'lexik_jwt_authentication.on_jwt_created' => 'onJwtCreated'
            ];
        }
    
        public function onJwtCreated(JWTCreatedEvent $event): void
        {
            $user = $event->getUser();
            // record your "last logged-in" according depending on your application set-up
    
        }
    }
    

    If you are not using this bundle, well, it depends how you are generating your tokens in the first place. But the basic idea would be the same: check for token generation and log that time.

    A caveat to take into account: if you are using any kind of "token refresh" to maintain sessions without needing to log-in again, each time you refresh the session you would generate a new token... and register a new log-in time.