PHPackages                             spiriitlabs/auth-log-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. spiriitlabs/auth-log-bundle

ActiveSymfony-bundle

spiriitlabs/auth-log-bundle
===========================

A Symfony bundle to log authentication events

v2.0.1(1w ago)9476—0%2MITPHPPHP &gt;=8.2CI passing

Since Sep 9Pushed 1w agoCompare

[ Source](https://github.com/SpiriitLabs/auth-log-bundle)[ Packagist](https://packagist.org/packages/spiriitlabs/auth-log-bundle)[ RSS](/packages/spiriitlabs-auth-log-bundle/feed)WikiDiscussions main Synced today

READMEChangelog (4)Dependencies (18)Versions (9)Used By (0)

SpiriitLabs Auth Log Bundle
===========================

[](#spiriitlabs-auth-log-bundle)

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.

[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/744f8821cc27dec8b0013ade48179731a44eadf4f943e0b1d9ffcb93f80177de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322532422d626c75652e737667)](https://php.net)[![Symfony](https://camo.githubusercontent.com/7080e14ab07861ec52aaf835597e0031c0cf1d585eb85bb50656cf14abd610c0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d362e34253242253743372e34253242253743382e302532422d626c75652e737667)](https://symfony.com)[![Latest Stable Version](https://camo.githubusercontent.com/7b8a60ac0f3596a0c8b8eec3e782948e0dbbcc923fc10e3a67421cfdbfc4b983/68747470733a2f2f706f7365722e707567782e6f72672f737069726969746c6162732f617574682d6c6f672d62756e646c652f762f737461626c652e737667)](https://packagist.org/packages/spiriitlabs/auth-log-bundle)[![CI Tests](https://github.com/SpiriitLabs/auth-log-bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/SpiriitLabs/auth-log-bundle/actions/workflows/ci.yml)

> **Upgrading from v1?** See the [UPGRADE.md](UPGRADE.md) guide for a step-by-step migration.

OWASP Authentication Best Practices
-----------------------------------

[](#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
--------

[](#features)

- **Authentication Event Logging**: Track successful logins with IP, user agent, timestamp and location
- **Geolocation Support**: Enrich logs with location data using GeoIP2 or IP API
- **Email Notifications**: Automatically alert users when a login from an unknown context is detected
- **Messenger Integration**: Optional async processing with Symfony Messenger
- **Repository-Based Persistence**: No factory or listener boilerplate — implement two interfaces in your repository and you're done
- **Extensible**: Replace the default email notification with any custom transport via `NotificationInterface`

Getting Started
---------------

[](#getting-started)

### 1. Install

[](#1-install)

```
composer require spiriitlabs/auth-log-bundle
```

### 2. Configure

[](#2-configure)

```
# config/packages/spiriit_auth_log.yaml
spiriit_auth_log:
    transports:
        sender_email: 'no-reply@yourdomain.com'
        sender_name: 'Security'
```

### 3. Implement `AuthLogUserInterface` on your User entity

[](#3-implement-authloguserinterface-on-your-user-entity)

`AuthLogUserInterface` extends `UserInterface`, so you no longer need to declare it explicitly.

```
use Spiriit\Bundle\AuthLogBundle\Entity\AuthLogUserInterface;

class User implements AuthLogUserInterface
{
    // ... your existing User fields

    public function getAuthLogEmail(): string
    {
        return $this->email;
    }

    public function getAuthLogDisplayName(): string
    {
        return $this->name;
    }
}
```

### 4. Create your log entity

[](#4-create-your-log-entity)

Extend `AbstractAuthenticationLog` and add a relation to your User entity:

```
use Doctrine\ORM\Mapping as ORM;
use Spiriit\Bundle\AuthLogBundle\Entity\AbstractAuthenticationLog;
use Spiriit\Bundle\AuthLogBundle\Entity\AuthLogUserInterface;
use Spiriit\Bundle\AuthLogBundle\FetchUserInformation\UserInformation;

#[ORM\Entity(repositoryClass: UserAuthLogRepository::class)]
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 $userInformation)
    {
        $this->user = $user;
        parent::__construct($userInformation);
    }

    public function getUser(): AuthLogUserInterface
    {
        return $this->user;
    }
}
```

### 5. Create the repository

[](#5-create-the-repository)

Your repository must implement two interfaces:

- `AuthenticationLogRepositoryInterface` — check if a log already exists and save new logs
- `AuthenticationLogCreatorInterface` — build the log entity from a user identifier and user information

```
use Doctrine\ORM\EntityRepository;
use Spiriit\Bundle\AuthLogBundle\AuthenticationLog\AuthenticationLogCreatorInterface;
use Spiriit\Bundle\AuthLogBundle\Entity\AbstractAuthenticationLog;
use Spiriit\Bundle\AuthLogBundle\FetchUserInformation\UserInformation;
use Spiriit\Bundle\AuthLogBundle\Repository\AuthenticationLogRepositoryInterface;

class UserAuthLogRepository extends EntityRepository implements
    AuthenticationLogRepositoryInterface,
    AuthenticationLogCreatorInterface
{
    public function save(AbstractAuthenticationLog $log): void
    {
        $this->getEntityManager()->persist($log);
        $this->getEntityManager()->flush();
    }

    public function findExistingLog(string $userIdentifier, UserInformation $userInformation): bool
    {
        return null !== $this->findOneBy([
            'user' => $userIdentifier,
            'ipAddress' => $userInformation->ipAddress,
        ]);
    }

    public function createLog(string $userIdentifier, UserInformation $userInformation): AbstractAuthenticationLog
    {
        $user = $this->getEntityManager()->getRepository(User::class)->findOneBy([
            'email' => $userIdentifier,
        ]);

        return new UserAuthLog($user, $userInformation);
    }
}
```

That's it! The bundle automatically listens to `LoginSuccessEvent`, checks if the login context is known, persists the log, and sends a notification email when a new context is detected.

Options
-------

[](#options)

### Geolocation

[](#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)

[](#messenger-async-processing)

```
spiriit_auth_log:
    messenger: 'messenger.default_bus'
```

Optional routing:

```
framework:
    messenger:
        routing:
            'Spiriit\Bundle\AuthLogBundle\Messenger\AuthLoginMessage\AuthLoginMessage': async
```

Events
------

[](#events)

When a new device/context is detected, the bundle dispatches a `AuthenticationLogEvents::NEW_DEVICE` event. You can listen to it for custom processing (logging, analytics, etc.):

```
use Spiriit\Bundle\AuthLogBundle\Listener\AuthenticationLogEvent;
use Spiriit\Bundle\AuthLogBundle\Listener\AuthenticationLogEvents;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(event: AuthenticationLogEvents::NEW_DEVICE)]
final class NewDeviceListener
{
    public function __invoke(AuthenticationLogEvent $event): void
    {
        $userIdentifier = $event->userIdentifier();
        $userInformation = $event->userInformation();

        // your custom logic here
    }
}
```

> **Note:** Persistence and notification are handled automatically by the bundle. You do **not** need to listen to this event for the bundle to work.

Custom Notification
-------------------

[](#custom-notification)

By default, the bundle sends email alerts via Symfony Mailer. To use a different transport (Slack, SMS, etc.), implement `NotificationInterface` and register it as a service:

```
use Spiriit\Bundle\AuthLogBundle\DTO\UserReference;
use Spiriit\Bundle\AuthLogBundle\FetchUserInformation\UserInformation;
use Spiriit\Bundle\AuthLogBundle\Notification\NotificationInterface;

final class SlackNotification implements NotificationInterface
{
    public function send(UserInformation $userInformation, UserReference $userReference): void
    {
        // send a Slack message, SMS, etc.
    }
}
```

Then point the `mailer` transport to your service ID:

```
spiriit_auth_log:
    transports:
        mailer: 'App\Notification\SlackNotification'
        sender_email: 'no-reply@yourdomain.com'
        sender_name: 'Security'
```

Custom Email Template
---------------------

[](#custom-email-template)

You can override the default email template:

[![Default email template](doc/images/ipApi.png)](doc/images/ipApi.png)

Create the file:

```
templates/bundles/SpiriitAuthLogBundle/new_device.html.twig

```

Available variables in the template:

VariableTypeDescription`userInformation.ipAddress``?string`Client IP address`userInformation.userAgent``?string`Browser / device user agent`userInformation.loginAt``?DateTimeImmutable`Login timestamp`userInformation.location``?LocateValues`Geolocation (city, country, latitude, longitude)`authenticableLog.displayName``string`User display name`authenticableLog.email``string`User emailArchitecture
------------

[](#architecture)

Internal flow when a user logs in:

1. `LoginListener` catches Symfony's `LoginSuccessEvent`
2. Builds a `LoginParameterDto` from the request (IP, user agent, user identifier)
3. Dispatches to `LoginService` (sync) or `AuthLoginMessage` (async via Messenger)
4. `LoginService` fetches geolocation data via `FetchUserInformation`
5. `DoctrineAuthenticationLogHandler` checks if the context is known (`findExistingLog`), and if not, creates and saves the log (`createLog` + `save`)
6. Dispatches `AuthenticationLogEvents::NEW_DEVICE` event
7. Sends notification via `NotificationInterface`

Testing
-------

[](#testing)

```
composer test              # Run the test suite
composer cs-check          # Check code style (dry-run)
composer cs-fix            # Fix code style
vendor/bin/phpstan analyse # Static analysis
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request

License
-------

[](#license)

This bundle is released under the MIT License. See the [LICENSE](LICENSE) file for details.

Support
-------

[](#support)

For questions and support, please contact  or open an issue on GitHub.

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance98

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~45 days

Total

5

Last Release

12d ago

Major Versions

v1.0.1 → v2.0.02026-03-09

### Community

Maintainers

![](https://www.gravatar.com/avatar/1807e890fb651ea404b659ae9e720c3d71020b13ed4385faaf79ae77d45fb3c6?d=identicon)[SpiriitLabs](/maintainers/SpiriitLabs)

---

Top Contributors

[![gilles-g](https://avatars.githubusercontent.com/u/377875?v=4)](https://github.com/gilles-g "gilles-g (31 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![OskarStark](https://avatars.githubusercontent.com/u/995707?v=4)](https://github.com/OskarStark "OskarStark (1 commits)")

---

Tags

owaspphpsecuritysymfony-bundle

###  Code Quality

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/spiriitlabs-auth-log-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/spiriitlabs-auth-log-bundle/health.svg)](https://phpackages.com/packages/spiriitlabs-auth-log-bundle)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.5M596](/packages/sylius-sylius)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M125](/packages/sulu-sulu)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.7k3.6M345](/packages/pimcore-pimcore)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k14.6k](/packages/prestashop-prestashop)[contao/core-bundle

Contao Open Source CMS

1231.6M2.0k](/packages/contao-core-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
