erikbelusic's avatar

login event handling in laravel 5

i am trying to hook to the login even in my L5 app to set last login time and IP address. i can make it work with the following:

Event::listen('auth.login', function($event)
{
    Auth::user()->last_login = new DateTime;
    Auth::user()->last_login_ip = Request::getClientIp();
    Auth::user()->save();
});

however, i am wondering what the best way to do this in L5 is with the event handler object. i tried creating an event handler and adding auth.login as an array key in the events service provider, however that didnt work. im not sure if that is possible or not with the auth.login event. if it isnt, where is the most appropriate place to put the above code. for testing, i put it in my routes.php file, but i know that isnt where it should be.

0 likes
10 replies
erikbelusic's avatar
erikbelusic
OP
Best Answer
Level 3

seemed to have come up with my own answer after some collaboration on stackoverflow

after working with both proposed answers, and some more research i finally figured out how to do this the way i was trying at first.

i ran the following artisan command

$ php artisan handler:event AuthLoginEventHandler

Then i altered the generated class removing the import of the Event class and and imported the user model. I also passed User $user and $remember to the handle method since when the auth.login event is fired, thats what is passed.

<?php namespace App\Handlers\Events;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use App\User;

class AuthLoginEventHandler {

    /**
     * Create the event handler.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  User $user
     * @param  $remember
     * @return void
     */
    public function handle(User $user, $remember)
    {
        dd("login fired and handled by class with User instance and remember variable");
    }

}

now i opened EventServiceProvided.php and modified the $listen array as follows:

protected $listen = [
    'auth.login' => [
        'App\Handlers\Events\AuthLoginEventHandler',
    ],
];

i realized if this doesn't work at first, you may need to

$ php artiasn clear-compiled

There we go! we can now respond to the user logging in via the auth.login event using an event handler class!

12 likes
bestmomo's avatar

I'm not sure that event handler object is always the best choice to listen events. Most of time this handler call another class. I still use L4 listen events style :

protected $listen = [
    'auth.login' => ['App\Services\Statut@setLoginStatut'],
    'auth.logout' => ['App\Services\Statut@setVisitorStatut'],
];

In this case I have a Statut class that manage user status for login and logout with 2 methods and I can get user as parameter.

pakogn's avatar

@erikbelusic , excuse me but in the way you reply the question, How do you get the last_login_ip?

1 like
erikbelusic's avatar

@pakogn - its been a while but i think you can use the request facade in your event handler

Request::getClientIp()
2 likes
ymutlu's avatar

If you are looking for 5.2 + events here they are. https://laravel.com/docs/5.2/authentication#events

'Illuminate\Auth\Events\Attempting' => [
        'App\Listeners\LogAuthenticationAttempt',
    ],

    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],

    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],

    'Illuminate\Auth\Events\Lockout' => [
        'App\Listeners\LogLockout',
    ],
3 likes
nam_co's avatar

Hi, Im trying to do the same thing in L5.4, but I can't get your first / simpler option to work, do you have any ideas?

    public function boot() {
        parent::boot();
        
        Event::listen('auth.login', function() {
            dd("it worked");
            //Auth::user()->last_login = new DateTime;
            //Auth::user()->last_login_ip = Request::getClientIp();
            //Auth::user()->save();
        });
    } ```

Appreciate any help you can give me , thanks
2 likes
asbjornpettersen's avatar

@nam_co Im probably a little late, but for others. If you want to add the Event::listen in the boot() method you have to change the listener from "auth.login" to "Illuminate\Auth\Events\Login"


public function boot()
{
    parent::boot();

    Event::listen('Illuminate\Auth\Events\Login', function() {
        dd("it worked");
    });
}
1 like

Please or to participate in this conversation.