Skip to content

Supported login types

The bundle hooks into a single extension point: Symfony's LoginSuccessEvent. The authenticator manager dispatches it on every successful authentication, whatever the authenticator — so any login mechanism built on the authenticator system works, with nothing to configure.

Login typeTriggeredNotes
form_loginon form submit
json_logine.g. the /api/login_check endpoint of LexikJWTAuthenticationBundle
login_link
remember_mewhen the cookie re-authenticates the user
Programmatic login (Security::login())
Custom authenticator (AbstractAuthenticator)
JWT (LexikJWT), access_token, http_basicstateless: fires on every request, see below
switch_user (impersonation)dispatches SwitchUserEvent, not LoginSuccessEvent

The authenticated user must implement AuthLogUserInterface — the listener ignores any other user class.

Stateless firewalls (JWT, access tokens)

Without a session, the token is re-authenticated on every request, and each one dispatches LoginSuccessEvent. Once the IP/device pair is known the check short-circuits — no log, no email — but every API request still pays for the geolocation lookup (if a provider is configured) and the "is this context known?" query, or a message on the bus in async mode.

Recommendations for high-traffic APIs

  • Prefer the GeoIP2 local database: an external HTTP call per request is a non-starter.
  • Enable async processing so the work happens in a worker.
  • To cover the initial login only, keep the login firewall in scope alone — the simplest way is a user class that does not implement AuthLogUserInterface when authenticated through the stateless firewall.

API Platform

API Platform delegates authentication to the Symfony firewall, and the bundle plugs in below it, at the security-component level: compatible out of the box. The JWT login endpoint (json_login) is the nominal case; Bearer-token requests fall under the stateless behavior above.

With login confirmation enabled, the email links are opened in a browser without a token — keep the confirmation route out of your stateless API firewall:

yaml
# config/packages/security.yaml
security:
    access_control:
        - { path: ^/auth-log/confirm, roles: PUBLIC_ACCESS }
        - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

Built and maintained by Spiriit — released under the MIT License.