Open-source project
rappasoft/laravel-authentication-log avatar
rappasoft/laravel-authentication-log

Laravel Authentication Log: device fingerprints, session history and new device alerts

Log user authentication details and send new device notifications.

999 stars117 forksPHPMIT

At a glance

What is it?
This package records every login with its IP, user agent, location and device fingerprint, warns a user when a new device appears, flags suspicious activity, and lets an application list and revoke sessions. The hard part it solves is not the logging, it is the fingerprint that has to survive a browser update.
Who is it for?
The package fits a Laravel application where sign-in history is a product requirement, where a user should be told when their account appears on a device they do not recognise, and where an administrator needs to revoke a session.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What it records, and who it notifies

Laravel Authentication Log tracks a user's authentication information, with the README naming login and logout time, IP, browser, location and device fingerprint among the fields, and it sends notifications via mail, Slack or SMS for new devices and failed logins.

The core feature list is the specification. Authentication logging tracks all login and logout attempts with the IP, the user agent, the location and the timestamps. Device fingerprinting gives reliable device identification using SHA-256 hashing with browser version normalization, which prevents false positives. Device names recognise browser-specific desktop and iOS user agents without changing the device fingerprints. New device detection automatically detects and notifies users of new device logins. Failed login tracking logs the attempts and can notify the user. Location tracking is an optional GeoIP integration, so it costs nothing for an installation that does not want it.

The advanced list adds the parts that turn a log into a security feature. Suspicious activity detection automatically detects multiple failed logins, rapid location changes and unusual login times, which are three signals that are cheap to compute and awkward to do yourself. Statistics and insights give total logins, failed attempts and unique devices. Session management lets an application view active sessions, revoke a specific session, or log out all other devices. Device trust management marks devices as trusted, manages their names, and can require a trusted device for sensitive actions. Rate limiting prevents notification spam with configurable limits, which is the difference between a useful alert and an alert nobody reads. Webhook support sends events to external services. Export to CSV or JSON gets the data out. Query scopes filter the log by successful, failed, suspicious, recent, by IP or by device. And middleware protects routes with a trusted device.

The project is MIT licensed, the primary language is PHP, the default branch is `main`, the last push was on 2026-10-09, and the recent releases are v6.1.2 from 2026-10-09, v6.1.1 from 2026-07-04 and v6.1.0 from 2026-06-10. The documentation is on the vendor's own site rather than in the repository.

A fingerprint has to survive a browser update

The device fingerprinting line in the feature list contains the whole difficulty of the package, and it is worth unpacking.

A fingerprint has to identify a device across many logins, months apart, and browsers change in between. A user agent string contains the browser version, so hashing the raw user agent produces a different fingerprint after a single update, and the user is told they signed in from a new device. The package's answer is SHA-256 hashing with browser version normalization, and the stated purpose is to prevent exactly those false positives.

The hashing is the security half and the normalization is the correctness half. SHA-256 gives a fixed length identifier that is cheap to store and index, and it is a one-way function, so the raw user agent is not sitting in the database where a support engineer might read it out. Normalizing the version is what keeps the identifier stable, and it is the part most implementations of this idea get wrong.

The second half of the design is that the name is separate from the fingerprint. Device names recognise browser-specific desktop and iOS user agents without changing the device fingerprints, so the interface can show a friendly label, a browser and a platform, while the identity used for the new device alert stays exactly as it was. A user can rename a device without becoming a new device, which is the behaviour a support conversation requires.

The trade is that a normalized fingerprint is a slightly weaker identifier, since two genuinely different devices with the same browser and platform can normalize to the same value. The package accepts that in exchange for not alarming users on every browser update, which is the right way round for a feature whose whole purpose is to be believed.

Session restoration is what makes naive logging noisy

The feature that distinguishes version 6.0.0 is session restoration prevention, and the reason it matters is that a login log without it is nearly useless.

The problem is that a page refresh and a remember me cookie both re-establish a session, and both look like a new sign-in to anything that watches the authentication event. So a user who reloads a page a few times has several login records, the statistics count a single sign-in many times, the new device detection has to be careful not to fire on the second one, and the whole table fills with entries that mean nothing.

The package prevents duplicate log entries from page refreshes and remember me cookies automatically, which means the log contains sign-ins rather than session restorations. That is the difference between a table you can put in front of a user and one that only a data engineer can read.

The version 6.0.0 release also brought improved device fingerprinting and enhanced statistics, and 6.1.0 added Laravel 13.x support and compatibility with immutable date casting, which is a small change that would otherwise break every date column in the log. The README points at `RELEASE_NOTES.md` for the complete details, and there is an `UPGRADE.md` in the repository as well, so the history of the schema is documented separately from the history of the code.

Suspicious activity and the channels it alerts through

The detection rules are three, and they are the classic ones. Multiple failed logins, which is a credential stuffing pattern or somebody guessing. Rapid location changes, which is a session that has been copied, and which is only meaningful because the location data is optional GeoIP rather than something inferred. And unusual login times, which is a heuristic, and the one that needs the least tuning and produces the most false positives if it is left alone.

The notification side is a separate decision. The package sends by mail, Slack or SMS, and the choice matters more than it looks. Mail is the default and the least alarming, which is right for a routine new device and wrong for a burst of failed logins. Slack is where a support team already is, and a webhook carries the same event to a system that can act on it automatically.

The webhook support is the extension point for a team that wants to do more than tell somebody. Combined with the query scopes, it means a rule can be written over the log itself, for example every failed login from a new device, and pushed to whatever system handles it, rather than relying on the built-in detection to be exactly what a team needs.

The rate limiting exists to make that workable. Without it, a user who fat-fingers a password on a phone in the rain generates a burst of failures and a burst of alerts, and an alert system that cries wolf is an alert system that gets switched off. The limit is configurable, which is what makes it usable at all.

Sessions and devices as an API, not a screen

A distinctive choice in this package is that the session and device management is exposed as methods on the user model rather than only as a settings screen, and the README shows the whole surface.

For sessions:

php
$activeSessions = $user->getActiveSessions();
$sessionCount = $user->getActiveSessionsCount();
$user->revokeSession($sessionId);
$user->revokeAllOtherSessions($currentDeviceId);
$user->revokeAllSessions();

The distinction between revoking all other sessions and revoking all sessions is the one that matters in practice. A user on a shared computer can log out the other sessions and keep their own, and a user who suspects a compromise can log out everything, which is the behaviour you want from a "sign out of all devices" button and which is easy to get wrong.

The statistics API is in the same style:

php
$stats = $user->getLoginStats();
$totalLogins = $user->getTotalLogins();
$failedAttempts = $user->getFailedAttempts();
$uniqueDevices = $user->getUniqueDevicesCount();

And the device trust model is what ties the two halves together. A device can be marked as trusted, the device name can be managed, and a trusted device can be required for sensitive actions, with middleware that protects routes accordingly. That is the mechanism that turns a security log into a policy, and it is why the package includes middleware at all.

For an application that wants to show the user their own history, the alternative is to build a settings screen over these calls, which is the point of exposing them.

Installing and upgrading: the publish tags matter

The installation is a Composer requirement, and the rest is the standard Laravel publishing dance.

bash
composer require rappasoft/laravel-authentication-log

The application then adds a trait to the user model, and the package provides one:

php
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;

class User extends Authenticatable
{
    use AuthenticationLoggable;
}

The migrations are published with a tag rather than with the default set, and then run:

bash
php artisan vendor:publish --provider="Rappasoft\LaravelAuthenticationLog\LaravelAuthenticationLogServiceProvider" --tag="authentication-log-migrations"
php artisan migrate

The configuration is optional and published the same way, with the tag `authentication-log-config`.

The upgrade path is the part with more care in it. For an existing installation coming from version 5.x or earlier, the package is updated with Composer, the upgrade migration is published with the same migrations tag, and the migrations are run. The README is specific about the safety of that step: the upgrade migration will only add columns if they do not exist, so it will safely add `device_id`, `device_name`, `is_trusted`, `last_activity_at`, `is_suspicious` and `suspicious_reason` to an existing `authentication_log` table without affecting existing data.

The breaking changes in version 6.0.0 are the two that affect a plan. Laravel 10.x support was dropped, with 6.1 and later supporting 11.x, 12.x and 13.x, and PHP 8.1 or later became the requirement, raised to 8.2 as of version 6.1.0. The upgrade guide in `docs/start/upgrade.md` has the detail.

Where this package is the wrong tool

The limits are about proportion and about the framework version matrix, and both are visible in the README.

The version matrix is the first. Laravel 8.x, 9.x and 10.x are served by the 1.x, 2.x and 3.x lines of the package, and the table says plainly that those give basic logging only. The full feature set, device fingerprinting, suspicious activity, webhooks and session management, starts with Laravel 11.x on version 5.x. So a team on Laravel 10 cannot have the interesting half of the package without moving the application, and a team that is on Laravel 10 and staying there should read the table before choosing this at all.

There is a second detail in the README that is easy to miss and important for a security package. Laravel 11 compatibility is retained, but its unpatched framework security advisories can block the Composer installation, and the README points at the installation requirements for the detail. The package is warning you that a security feature is a poor excuse for running an unpatched framework, which is a reasonable position for a package whose job is to tell users when their account appears somewhere new.

The second limit is proportion. The package installs a trait, a table, a configuration, notification channels, a device trust model, middleware and a web framework of its own, and all of that is justified when sign-in history is a feature. An application that only wants a last login timestamp and a user agent column should write two columns and a listener, and a team that has done that has also avoided a dependency with its own version matrix, its own notification configuration and its own upgrade migrations.

The alternative, for the teams that do want the features, is to build the equivalent from the framework's own events and the session store, which is a project rather than a weekend. The difference in approach is that this package has already decided what a device fingerprint is and how a new device is defined, and a team that agrees with those decisions saves itself the work, while a team that wants its own definition ends up fighting the package's.

Editorial conclusion

The package fits a Laravel application where sign-in history is a product requirement, where a user should be told when their account appears on a device they do not recognise, and where an administrator needs to revoke a session. It is the wrong tool for an application that only needs a last login timestamp, where the trait, the migrations, the notifications and the device trust model are all overhead, and it is the wrong choice on a Laravel version outside the supported matrix, where you would be running the 1.x to 3.x lines with basic logging only. Before installing it, read the version compatibility table in the README, check the framework security advisories for your Laravel version, since the package itself notes that unpatched advisories on Laravel 11 can block the installation, and decide whether the notification channels you configure should be mail, Slack or SMS before the first login reaches production.

Frequently asked questions

How do I install Laravel Authentication Log?

Run `composer require rappasoft/laravel-authentication-log`, add the AuthenticationLoggable trait to your user model, then publish the migrations with the vendor:publish command using the `authentication-log-migrations` tag and run `php artisan migrate`. The configuration is published separately with the `authentication-log-config` tag.

Which Laravel versions does Laravel Authentication Log support?

Version 6.1 and later support Laravel 11.x, 12.x and 13.x with PHP 8.2 or later, and version 5.x covers Laravel 11.x and 12.x. For Laravel 10.x use version 3.x, and the 1.x, 2.x and 3.x lines for Laravel 8.x, 9.x and 10.x give basic logging only.

How does Laravel Authentication Log fingerprint a device?

With SHA-256 hashing and browser version normalization, which prevents false positives when the browser updates. The friendly device name is kept separate and recognises browser-specific desktop and iOS user agents without changing the fingerprint used for the new device detection.

Can I list and revoke a user's sessions with Laravel Authentication Log?

Yes. getActiveSessions() and getActiveSessionsCount() list the sessions, and revokeSession(), revokeAllOtherSessions() and revokeAllSessions() remove them. There is also device trust management, so a device can be marked as trusted and required by middleware for sensitive actions.

Official sources

  1. Issues
  2. License: MIT
  3. rappasoft/laravel-authentication-log on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rappasoft-laravel-authentication-log.svg)](https://hysenlabs.com/projects/rappasoft-laravel-authentication-log)

Was this useful?