spiriitlabs / auth-log-bundle
A Symfony bundle to log authentication events
Installs: 368
Dependents: 0
Suggesters: 0
Security: 0
Stars: 7
Watchers: 0
Forks: 2
Open Issues: 0
Type:symfony-bundle
pkg:composer/spiriitlabs/auth-log-bundle
Requires
- php: >=8.2
- doctrine/orm: 3.* || ^4.0
- symfony/config: ^6.4|^7.4|^8.0
- symfony/dependency-injection: ^6.4|^7.4|^8.0
- symfony/event-dispatcher: ^6.4|^7.4|^8.0
- symfony/framework-bundle: ^6.4|^7.4|^8.0
- symfony/http-client: ^6.4|^7.4|^8.0
- symfony/mailer: ^6.4|^7.4|^8.0
- symfony/messenger: ^6.4|^7.4|^8.0
- symfony/security-bundle: ^6.4|^7.4|^8.0
- symfony/translation: ^6.4|^7.4|^8.0
- symfony/translation-contracts: ^1.0|^2.0|^3.0
- symfony/twig-bundle: ^6.4|^7.4|^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.64
- phpstan/phpstan: ^2.1
- phpstan/phpstan-symfony: ^2.0
- rector/rector: ^2.1
- symfony/phpunit-bridge: ^6.4|^7.4|^8.0
- symfony/yaml: ^6.4|^7.4|^8.0
Suggests
- geoip2/geoip2: Required if you want to enrich logs with geolocation
This package is auto-updated.
Last update: 2026-02-02 07:23:53 UTC
README
With this Symfony bundle you can send an email alert when a user logs in from a new context — for example:
- a different IP address
- a different location (geolocation)
- a different User Agent (device/browser)
This helps detect unusual login activity early and increases visibility into authentication events.
OWASP Authentication Best Practices
To ensure strong authentication security, this bundle aligns with guidance from the OWASP Authentication Cheat Sheet by:
- Treating authentication failures or unusual logins as events worthy of detection and alerting
- Ensuring all login events are logged, especially when the context changes (IP, location, device)
- Using secure channels (TLS) for all authentication-related operations
- Validating and normalizing incoming data (e.g. user agent strings, IP addresses) to avoid ambiguity or spoofing
Features
- Authentication Event Logging: Track successful logins with detailed information
- Geolocation Support: Enrich logs with location data using GeoIP2 or IP API
- Email Notifications: Send email alerts for authentication events
- Messenger Integration: Optional processing with Symfony Messenger
- Highly Configurable: Flexible configuration options for various use cases
- Extensible: Easy to extend with custom authentication log entities
Getting Started
1. Install
composer require spiriitlabs/auth-log-bundle
2. Configure
# config/packages/spiriit_auth_log.yaml spiriit_auth_log: transports: sender_email: 'no-reply@yourdomain.com' sender_name: 'Security'
3. Implement AuthenticableLogInterface on your User
use Spiriit\Bundle\AuthLogBundle\Entity\AuthenticableLogInterface; class User implements UserInterface, AuthenticableLogInterface { public function getAuthenticationLogFactoryName(): string { return 'user'; } public function getAuthenticationLogsToEmail(): string { return $this->email; } public function getAuthenticationLogsToEmailName(): string { return $this->name; } }
4. Create your log entity
use Spiriit\Bundle\AuthLogBundle\Entity\AbstractAuthenticationLog; #[ORM\Entity] class UserAuthLog extends AbstractAuthenticationLog { #[ORM\Id, ORM\GeneratedValue, ORM\Column] private ?int $id = null; #[ORM\ManyToOne(targetEntity: User::class)] private User $user; public function __construct(User $user, UserInformation $info) { $this->user = $user; parent::__construct($info); } public function getUser(): AuthenticableLogInterface { return $this->user; } }
5. Create the factory
use Spiriit\Bundle\AuthLogBundle\AuthenticationLogFactory\AuthenticationLogFactoryInterface; class UserAuthLogFactory implements AuthenticationLogFactoryInterface { public function __construct(private EntityManagerInterface $em) {} public function createUserReference(string $userIdentifier): UserReference { $user = $this->em->getRepository(User::class)->findOneBy(['email' => $userIdentifier]); return new UserReference(type: 'user', id: (string) $user->getId()); } public function isKnown(UserReference $ref, UserInformation $info): bool { return (bool) $this->em->createQueryBuilder() ->select('l')->from(UserAuthLog::class, 'l') ->where('l.user = :id AND l.ipAddress = :ip AND l.userAgent = :ua') ->setParameters(['id' => $ref->id, 'ip' => $info->ipAddress, 'ua' => $info->userAgent]) ->getQuery()->getOneOrNullResult(); } public function supports(): string { return 'user'; } // must match getAuthenticationLogFactoryName() }
6. Listen to the event
use Spiriit\Bundle\AuthLogBundle\Listener\{AuthenticationLogEvent, AuthenticationLogEvents}; class AuthLogListener implements EventSubscriberInterface { public function __construct(private EntityManagerInterface $em) {} public static function getSubscribedEvents(): array { return [AuthenticationLogEvents::NEW_DEVICE => 'onNewDevice']; } public function onNewDevice(AuthenticationLogEvent $event): void { $user = $this->em->getRepository(User::class)->find($event->getUserReference()->id); $log = new UserAuthLog($user, $event->getUserInformation()); $this->em->persist($log); $this->em->flush(); // persist log or custom process $event->markAsHandled(); // Required to continue the notification process } }
Options
Geolocation
GeoIP2 (local database):
spiriit_auth_log: location: provider: 'geoip2' geoip2_database_path: '%kernel.project_dir%/var/GeoLite2-City.mmdb'
IP API (external API, 45 req/min free):
spiriit_auth_log: location: provider: 'ipApi'
Messenger (async processing)
spiriit_auth_log: messenger: 'messenger.default_bus'
Optional routing:
framework: messenger: routing: 'Spiriit\Bundle\AuthLogBundle\Messenger\AuthLoginMessage\AuthLoginMessage': async
Custom email template
Template
You can use the default template, not recommended indeed!
Override here
Create the file:
templates/bundles/SpiriitAuthLogBundle/new_device.html.twig
The userInformation object contains: ipAddress, userAgent, loginAt, location (city, country, latitude, longitude).
Testing
Run the test suite:
vendor/bin/simple-phpunit
Contributing
Contributions are welcome! Please feel free to submit a Pull Request
License
This bundle is released under the MIT License. See the LICENSE file for details.
Support
For questions and support, please contact dev@spiriit.com or open an issue on GitHub.
