I have a Symfony 3.2 application which exposes a REST API and uses Json Web Tokens (JWT) for authentication. I recently switched to using Symfony's Guard component. Now my security.yml
contains a firewall config section as follows (I'm using the Lexik JWT bundle 2.4.0, but this shouldn't matter):
firewalls:
# ...
api:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
Since I did this switch, I notice that every request is handled as if the user just logged in, i.e. a security.interactive_login
event is fired.
In the docs (http://symfony.com/doc/current/components/security/authentication.html#authentication-events) it states:
The security.interactive_login event is triggered after a user has actively logged into your website. It is important to distinguish this action from non-interactive authentication methods, such as: authentication based on a "remember me" cookie, authentication based on your session, authentication using a HTTP basic or HTTP digest header. You could listen on the security.interactive_login event, for example, in order to give your user a welcome flash message every time they log in.
So I definitely don't expect this event for every request - I'd rather expect to get the security.authentication.success
event on every request, as pointed out in the docs.
However, Symfony's GuardAuthenticatorHandler
class dispatches the security.interactive_login
event in its authenticateWithToken
method, and this method is called by the GuardAuthenticationListener
on every request.
Is that a bug in Symfony, a misunderstanding on my side, or due to incorrect configuration?
(This is not a philosophical question - in my case it leads to the concrete problem that the last login time of the user is updated on every request, which does not make sense.)
I've come across your issue, because I've exactly the same problem. My workaround is to add a attribute in the request object, right before return true in the supports method of the guard.
Example:
public function supports(Request $request)
{
...
$request->attributes->set('is_interactive_login', true);
return true;
}
With this information you can check if it was a interactive login in the event listener
Example:
public function onLoginSuccess(InteractiveLoginEvent $event)
{
$request = $event->getRequest();
if ($request->attributes->get('is_interactive_login', false)) {
// do whatever you need todo on interactive login
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With