Laravel Authentication Log is a package Log user authentication details and send new device notifications.

Overview

Package Logo

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Laravel Authentication Log is a package which tracks your user's authentication information such as login/logout time, IP, Browser, Location, etc. as well as sends out notifications via mail, slack, or sms for new devices and failed logins.

Installation

You can install the package via composer:

composer require rappasoft/laravel-authentication-log

If you want the location features you must also install torann/geoip:

composer require torann/geoip

You can publish and run the migrations with:

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

You can publish the view/email files with:

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

You can publish the config file with:

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

This is the contents of the published config file:

return [
    // The database table name
    // You can change this if the database keys get too long for your driver
    'table_name' => 'authentication_log',

    'notifications' => [
        'new-device' => [
            // Send the NewDevice notification
            'enabled' => env('NEW_DEVICE_NOTIFICATION', true),

            // Use torann/geoip to attempt to get a location
            'location' => true,

            // The Notification class to send
            'template' => \Rappasoft\LaravelAuthenticationLog\Notifications\NewDevice::class,
        ],
        'failed-login' => [
            // Send the FailedLogin notification
            'enabled' => env('FAILED_LOGIN_NOTIFICATION', false),

            // Use torann/geoip to attempt to get a location
            'location' => true,

            // The Notification class to send
            'template' => \Rappasoft\LaravelAuthenticationLog\Notifications\FailedLogin::class,
        ],
    ],

    // When the clean-up command is run, delete old logs greater than `purge` days
    // Don't schedule the clean-up command if you want to keep logs forever.
    'purge' => 365,
];

If you installed torann/geoip you should also publish that config file to set your defaults:

php artisan vendor:publish --provider="Torann\GeoIP\GeoIPServiceProvider" --tag=config

Configuration

You must add the AuthenticationLoggable and Notifiable traits to the models you want to track.

use Illuminate\Notifications\Notifiable;
use Rappasoft\LaravelAuthenticationLog\Traits\AuthenticationLoggable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable, AuthenticationLoggable;
}

The package will listen for Laravel's Login, Logout, Failed, and OtherDeviceLogout events.

Usage

Get all authentication logs for the user:

User::find(1)->authentications;

Get the user's last login information:

User::find(1)->lastLoginAt();

User::find(1)->lastSuccessfulLoginAt();

User::find(1)->lastLoginIp();

User::find(1)->lastSuccessfulLoginIp();

Get the user's previous login time & IP address (ignoring the current login):

auth()->user()->previousLoginAt();

auth()->user()->previousLoginIp();

Notifications

Notifications may be sent on the mail, nexmo, and slack channels but by default notify via email.

You may define a notifyAuthenticationLogVia method on your authenticatable models to determine which channels the notification should be delivered on:

public function notifyAuthenticationLogVia()
{
    return ['nexmo', 'mail', 'slack'];
}

You must install the Slack and Nexmo drivers to use those routes and follow their documentation on setting it up for your specific authenticatable models.

New Device Notifications

Enabled by default, they use the \Rappasoft\LaravelAuthenticationLog\Notifications\NewDevice class which can be overridden in the config file.

Failed Login Notifications

Disabled by default, they use the \Rappasoft\LaravelAuthenticationLog\Notifications\FailedLogin class which can be overridden in the config file.

Location

If the torann/geoip package is installed, it will attempt to include location information to the notifications by default.

You can turn this off within the configuration for each template.

Note: By default when working locally, no location will be recorded because it will send back the default address from the geoip config file. You can override this behavior in the email templates.

Purging Old Logs

You may clear the old authentication log records using the authentication-log:purge Artisan command:

php artisan authentication-log:purge

Records that are older than the number of days specified in the purge option in your config/authentication-log.php will be deleted.

'purge' => 365,

You can also schedule the command at an interval:

$schedule->command('authentication-log:purge')->monthly();

Displaying The Log

You can set up your own views and paginate the logs using the user relationship as normal, or if you also use my Livewire Tables plugin then here is an example table:

Note: This example uses the jenssegers/agent package which is included by default with Laravel Jetstream as well as jamesmills/laravel-timezone for displaying timezones in the users local timezone. Both are optional, modify the table to fit your needs.



namespace App\Http\Livewire;

use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Jenssegers\Agent\Agent;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelAuthenticationLog\Models\AuthenticationLog as Log;

class AuthenticationLog extends DataTableComponent
{
    public string $defaultSortColumn = 'login_at';
    public string $defaultSortDirection = 'desc';
    public string $tableName = 'authentication-log-table';

    public User $user;

    public function mount(User $user)
    {
        if (! auth()->user() || ! auth()->user()->isAdmin()) {
            $this->redirectRoute('frontend.index');
        }

        $this->user = $user;
    }

    public function columns(): array
    {
        return [
            Column::make('IP Address', 'ip_address')
                ->searchable(),
            Column::make('Browser', 'user_agent')
                ->searchable()
                ->format(function($value) {
                    $agent = tap(new Agent, fn($agent) => $agent->setUserAgent($value));
                    return $agent->platform() . ' - ' . $agent->browser();
                }),
            Column::make('Location')
                ->searchable(function (Builder $query, $searchTerm) {
                    $query->orWhere('location->city', 'like', '%'.$searchTerm.'%')
                        ->orWhere('location->state', 'like', '%'.$searchTerm.'%')
                        ->orWhere('location->state_name', 'like', '%'.$searchTerm.'%')
                        ->orWhere('location->postal_code', 'like', '%'.$searchTerm.'%');
                })
                ->format(fn($value) => $value['default'] === false ? $value['city'] . ', ' . $value['state'] : '-'),
            Column::make('Login At')
                ->sortable()
                ->format(fn($value) => $value ? timezone()->convertToLocal($value) : '-'),
            Column::make('Login Successful')
                ->sortable()
                ->format(fn($value) => $value === true ? 'Yes' : 'No'),
            Column::make('Logout At')
                ->sortable()
                ->format(fn($value) => $value ? timezone()->convertToLocal($value) : '-'),
            Column::make('Cleared By User')
                ->sortable()
                ->format(fn($value) => $value === true ? 'Yes' : 'No'),
        ];
    }

    public function query(): Builder
    {
        return Log::query()
            ->where('authenticatable_type', User::class)
            ->where('authenticatable_id', $this->user->id);
    }
}
">
<livewire:authentication-log :user="$user" />

Example:

Example Log Table

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

Comments
  • Refresh logged as a login

    Refresh logged as a login

    Whenever you refresh/visit a new page, a successful login is logged into the database. This is creating a huge log per user. As the screenshot suggests, over time these logs will grow too much Screenshot from 2021-10-23 21-24-54 .

    opened by mainadennis 14
  • syntax error, unexpected '(' on LoginListener

    syntax error, unexpected '(' on LoginListener

    After firing the Login Event event(new Login('web', $user, $request->remember_me)); the package produces this error:

    
    "message": "syntax error, unexpected '('",
    "exception": "ParseError",
     "file": ". . .\\vendor\\rappasoft\\laravel-authentication-log\\src\\Listeners\\LoginListener.php",
    "line": 21,
    
    //...
    
    

    Any help afforded will be appreciated.

    Thank you.

    EDIT: The package was installed today (11/28/2021 12:28 GMT) using composer require rappasoft/laravel-authentication-log I am using WAMP64 with PHP 7.4 installed, Laravel V8.73.1

    opened by johnngondi 8
  • Laravel 9.x Compatibility

    Laravel 9.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 9.x.

    Before merging, you need to:

    • Checkout the l9-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 5
  • Logout listener bug fix

    Logout listener bug fix

    This should remedy and close the following bug:

    #8 - The Logout listener was grabbing the first record instead of the latest, causes records to not be updated on logout

    opened by logan-jobzmall 3
  • Added extra where clause to known variable

    Added extra where clause to known variable

    Checked for a successful login only.

    When a failed login attempt happens the user can receive a notification stating it failed. However, if that same device then successfully signs in the user is not informed about the successful login. From a security stand point the user doesn't know that the bad actor gained access after a failed attempt.

    opened by JustinByrne 2
  • Missing

    Missing "down" function to migration

    Hey there,

    The migration file here https://github.com/rappasoft/laravel-authentication-log/blob/main/database/migrations/create_authentication_log_table.php.stub is missing a down function to drop the table.

    its not a big thing, but nice to have

    opened by zaherg 2
  • [Bug] Logout Listener grabs first instead of latest

    [Bug] Logout Listener grabs first instead of latest

    When logging out, the Logout Listener grabs the first occurrence of the log for that user at that ip, and then updates the logout_at of that one, which was not the latest record.

    I wouldn't mind contributing to this project if you don't have time to fix it.

    opened by logan-jobzmall 2
  • This cache store does not support tagging.

    This cache store does not support tagging.

    I did not find anything in the documentation of this package regarding caching, so I left my CACHE_DRIVER=file. But by doing so, right after installing the package and logging in, I get This cache store does not support tagging.

    vendor/laravel/framework/src/Illuminate/Cache/Repository.php:495

    Again, I reported this as a bug, since there is no mention regarding the cache in the docs. Removing the package "solved" the problem.

    opened by MrMooky 2
  • Translations are not loaded

    Translations are not loaded

    I used the French language, but the emails are partially translated. In fact there is only one term that is translated.

    image

    As seen in this screenshot, only the last one is translated.

    I searched but I do not understand where it can come from.

    opened by forxer 1
  • Fixed issue with getting previous login at and previous login IP.

    Fixed issue with getting previous login at and previous login IP.

    When using:

    auth()->user()->previousLoginAt();
    // or
    auth()->user()->previousLoginIp();
    

    They currently do not skip ALL failed login attempts.

    For instance, if there is a failed login attempt prior to the current successful login, it will retrieve and return the failed login details.

    With this pull request it will fix that issue and skip the failed login attempts and give the true successful previous login.

    opened by codebyray 0
  • v1.3.0

    v1.3.0

    Changed

    • Added missing hasTranslations() - https://github.com/rappasoft/laravel-authentication-log/pull/30
    • Improve translation strings - https://github.com/rappasoft/laravel-authentication-log/pull/31
    opened by rappasoft 0
  • Login for other models triggers listener BadMethodCallException

    Login for other models triggers listener BadMethodCallException

    I have three different models that can login to my application: Users, Applications, Enrolments. They are completely different models as they do completely different things. All start like this:

    class User extends Authenticatable implements MustVerifyEmail

    class Application extends Authenticatable implements MustVerifyEmail

    class Enrolment extends Authenticatable implements MustVerifyEmail

    but only User has use AuthenticationLoggable;

    When an Application or an Enrolment logs in the Login event is triggered and the rappasoft listener Rappasoft\LaravelAuthenticationLog\Listeners\LoginListener::handle responds to it and fails:

    $user = $event->user;
    $ip = $this->request->ip();
    $userAgent = $this->request->userAgent();
    $known = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->whereLoginSuccessful(true)->first();
    $newUser = Carbon::parse($user->{$user->getCreatedAtColumn()})->diffInMinutes(Carbon::now()) < 1;
    

    i.e. when $known = $user->authentications() is called.

    I think the listener should stop responding if the user model doesn't use AuthenticationLoggable

    Could be the problem in #33 too?

    opened by colinmackinlay 0
  • Optimize Other Devices Logout Listener

    Optimize Other Devices Logout Listener

    Currently, when logging out of other devices, the listener updates every record for the given user, on a large dataset this can be hundreds of queries. By limiting the scope of the records to only the ones that are not logged out, the number of queries is reduced to a minimum amount.

    opened by nessimabadi 3
  • SQL exception at logout

    SQL exception at logout

    Hi,

    your package v1.x returns SQL error at logout:

    Illuminate\Database\QueryException
    SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]A column has been specified more than once in the order by list. Columns in the order by list must be unique. (SQL: select top 1 * from [authentication_log] where [authentication_log].[authenticatable_type] = App\User and [authentication_log].[authenticatable_id] = 3 and [authentication_log].[authenticatable_id] is not null and [ip_address] = ::1 and [user_agent] = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 order by [login_at] desc, [login_at] desc)
    

    which can be resolved by replacing: $log = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->orderByDesc('login_at')->first(); with $log = $user->authentications()->whereIpAddress($ip)->whereUserAgent($userAgent)->first();

    opened by Crouxie 0
  • UserAgent triggering false new device notifications

    UserAgent triggering false new device notifications

    This packages works great, just I'm experiencing a few "false" new device notifications.

    My question is should a user get a notification if they have updated their browser?

    Take these two UserAgent strings:

    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15

    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15

    I'd suggest the version should be ignored?

    opened by sunscreem 5
  • Model exception

    Model exception

    I integrated AuthenticationLoggable to 2 model User and Company. AdminUser is without trait but it throws exception in login

    image

    All models have diff guards but it still throws an error

    [2022-01-13 16:55:47] staging.ERROR: Call to undefined method App\Models\AdminUser::authentications() {"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method App\\Models\\AdminUser::authentications() at /Users/arturas/code/Artme/wil/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:71)
    [stacktrace]
    #0 /Users/arturas/code/Artme/wil/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(36): Illuminate\\Database\\Eloquent\\Model::throwBadMethodCallException('authentications')
    #1 /Users/arturas/code/Artme/wil/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2132): Illuminate\\Database\\Eloquent\\Model->forwardCallTo(Object(Illuminate\\Database\\Eloquent\\Builder), 'authentications', Array)
    #2 /Users/arturas/code/Artme/wil/vendor/rappasoft/laravel-authentication-log/src/Listeners/LoginListener.php(30): Illuminate\\Database\\Eloquent\\Model->__call('authentications', Array)
    
    opened by keizah7 2
Releases(v2.0.0)
  • v2.0.0(Feb 19, 2022)

  • v1.3.0(Jan 18, 2022)

    Changed

    • Added missing hasTranslations() - https://github.com/rappasoft/laravel-authentication-log/pull/30
    • Improve translation strings - https://github.com/rappasoft/laravel-authentication-log/pull/31
    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Dec 2, 2021)

    Added

    • Added latestAuthentication relationship - https://github.com/rappasoft/laravel-authentication-log/pull/24

    Changed

    • Fixed issue with PHP 7.4 - https://github.com/rappasoft/laravel-authentication-log/pull/22
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Nov 22, 2021)

    Added

    • Fire a successful login after a failed login on an unknown (new) device. - https://github.com/rappasoft/laravel-authentication-log/pull/15
    • Make the events the package is listening for configurable in the config file
    • Added French translation and missing location translations - https://github.com/rappasoft/laravel-authentication-log/pull/18
    • PHP 7.4 Support
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Oct 21, 2021)

  • v1.1.0(Oct 11, 2021)

  • v1.0.0(Oct 1, 2021)

Owner
Anthony Rappa
Certified Laravel | Laravel Boilerplate Creator
Anthony Rappa
This package adds support for verifying new email addresses: when a user updates its email address, it won't replace the old one until the new one is verified.

Laravel Verify New Email Laravel supports verifying email addresses out of the box. This package adds support for verifying new email addresses. When

Protone Media 300 Dec 30, 2022
27Laracurl Laravel wrapper package for PHP cURL class that provides OOP interface to cURL. [10/27/2015] View Details

Laracurl Laravel cURL Wrapper for Andreas Lutro's OOP cURL Class Installation To install the package, simply add the following to your Laravel install

zjango 8 Sep 9, 2018
Log user authentication actions in Laravel.

Laravel Auth Log The laravel-auth-log package will log all the default Laravel authentication events (Login, Attempting, Lockout, etc.) to your databa

Label84 29 Dec 8, 2022
Razorpay payment gateway integration in laravel with submit form and storing details in payment table.

Integrating razorpay payment gateway in laravel with submit form and storing payment details in payment table. How to settup the project in your local

Mohammed-Thamnees 3 Apr 15, 2021
A blog website with blog details with laravel

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

PreshDev 3 Mar 6, 2022
User authentication REST API with Laravel (Register, Email verification, Login, Logout, Logged user data, Change password, Reset password)

User Authentication API with Laravel This project is a user authentication REST API application that I developed by using Laravel and MySql. Setup Fir

Yusuf Ziya YILDIRIM 3 Aug 23, 2022
Laravel 2-Step Verification is a package to add 2-Step user authentication to any Laravel project easily.

Laravel 2-Step verification is a package to add 2-Step user authentication to any Laravel project easily. It is configurable and customizable. It uses notifications to send the user an email with a 4-digit verification code. Laravel 2-Step Authentication Verification for Laravel. Can be used in out the box with Laravel's authentication scaffolding or integrated into other projects.

Jeremy Kenedy 204 Dec 23, 2022
Laravel Podcast is Laravel 5.5 web app that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI and User Authentication.

Laravel Podcast is Laravel 5.5 web app that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI and

Jeremy Kenedy 35 Dec 19, 2022
Sweetalert and Toaster notifications for Laravel livewire with support for tailwind and bootstrap.

Larabell Integrate livewire with sweetalert. Installation How to use Sweetalert Toast Available configuration Installation composer require simtabi/la

Simtabi 3 Jul 27, 2022
Laravel 5 Flash Notifications with icons and animations and with a timeout

Notify (Laravel) Notify alert boxes to the browser with sound and font awesome icons and give it a timeout to fly out. Works great to notify the user

Ben-Piet O'Callaghan 31 Oct 8, 2022
GeoLocation-Package - This package helps you to know the current language of the user, the country from which he is browsing, the currency of his country, and also whether he is using it vpn

GeoLocation in PHP (API) ?? ?? ?? This package helps you to know a lot of information about the current user by his ip address ?? ?? ?? This package h

Abdullah Karam 4 Dec 8, 2022
This package provides new helper functions that take care of handling all the translation hassle and do it for you.

Laravel Translate Message ?? This package provides new helper functions that take care of handling all the translation hassle and do it for you. Insta

Basel Rabia 17 Feb 8, 2022
A Laravel package helps you add a complete real-time messaging system to your new / existing application with only one command.

A Laravel package helps you add a complete real-time messaging system to your new / existing application with only one command.

Munaf Aqeel Mahdi 1.7k Jan 5, 2023
Save Model is a Laravel package that allows you to save data in the database in a new way.

Save Model is a Laravel package that allows you to save data in the database in a new way. No need to worry about $guarded and $fillable properties in the model anymore. Just relax an use Save Model package.

Laratips 27 Mar 2, 2022
Renamify is a package for Laravel used to rename a file before uploaded to prevent replacing exists file which has the same name to this new uploaded file.

Renamify Laravel package for renaming file before uploaded on server. Renamify is a package for Laravel used to rename a file before uploaded to preve

MB'DUSENGE Callixte 2 Oct 11, 2022
This Package helps you in laravel application to log all desired activity for each request from request entry point to generate response at a single snapshot.

Laravel Scenario Logger This Package helps you in laravel application to log all desired activity for each request from request entry point to generat

Mehrdad Mahdian 6 Sep 27, 2021
A simple Laravel event log package for easy model based logging.

Karacraft Logman A simple Model Event Logging Package Usage Installation composer require karacraft/logman Migrate php artisan migrate Publish php a

Karacraft 0 Dec 28, 2021
This package provides a Logs page that allows you to view your Laravel log files in a simple UI

A simplistics log viewer for your Filament apps. This package provides a Logs page that allows you to view your Laravel log files in a simple UI. Inst

Ryan Chandler 9 Sep 17, 2022
Laravel telegram log is a package that can catch your logs all quite simply

Laravel Telegram log Laravel telegram log is a package that can catch your logs all quite simply. Requirments This package is tested with Laravel v8 i

Muath Alsowadi 4 Aug 3, 2022