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.
just did it this way
For 5.2 something like this
in Listeners:
In EventServiceProvider.php :
EDIT: this only works in 5.0.* and 5.1.*.
For the 5.2.* solution see JuLiAnc response below.
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
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.now i opened EventServiceProvided.php and modified the
$listen
array as follows:i realized if this doesn't work at first, you may need to
There we go! we can now respond to the user logging in via the auth.login event using an event handler class!
In laravel 5.2; auth.login won't work... the following will have to be used:
As stated in the documentation here
Open up EventServiceProvider.php and in boot method you can listen for
'auth.login'
event via callback.You may want to create listener so you move callback function somewhere else. Do that following this http://laravel.com/docs/4.2/events#using-classes-as-listeners
Be careful about asking what the best way to do X is, because Laravel, in particular, provides many ways of accomplishing the same task -- some are better than others in certain situations.
Taking a look at the Laravel documentation, personally I would go with the "Basic Usage" as it seems to match the use case you have stated.
If we run the following Artisan command we can generate a template for the UserLoggedIn event.
(note the past tense, because events happen, and then the subscribers are notified of the event having taken place)
(note 2: the
app
string in namespaces is what Laravel uses out of the box, it is likely different for you if you have executed thephp artisan app:name
command)The following class is generated for us:
If we add a
userId
parameter to the constructor, then the event doesn't need to know about the Auth Facade/Guard Contract. This means ourUserLoggedIn
event code is not tightly coupled to Eloquent or which ever authentication framework you decide to utilize in your app. Anyways, let's add thatuserId
parameter.Now you're probably wondering, well that's great and all, but how to we act on this event? Great question! We need to create an event handler to handle when this event is fired. Let's do that now using Artisan:
We name our new event handler
UpdateUserMetaData
and tell Artisan that the event we want to handle is theUserLoggedIn
event.Now we have some code that looks like this inside of
app/Handlers/Events/UpdateUserMetaData.php
:We can update the handle method to be able to handle this event like you specified above quite easily:
As a side note, if you're not familiar with Carbon, you might want to look into using it so you can take advantage of its fantastic API like you can with Eloquent's
created_at
andupdated_at
timestamp fields on most models. Here's a link for how to tell Eloquent which fields should be used with Carbon: http://laravel.com/docs/master/eloquent#date-mutators.There are two final steps we have to perform before this code will work in your Laravel app.
We need to map the event to the event handler in the
EventServiceProvider
class under theapp/Providers
directory.We need to fire the event after login.
To complete the first step, we just need to add our event classes to the
$listeners
property inapp/Providers/EventServiceProvder.php
like so:The above will work provided you import the classes inside the
EventServiceProvider
class, and you are using PHP 5.5. If you're using a lower PHP version, you'll need to provide the full path to each class as a string like this:'app/Events/UserLoggedIn'
and'app/Handlers/Events/UpdateUserMetaData'
.The
$listeners
array maps events to their respective handlers.Okay, now for the final step! In your code base, find the place where the user is authenticated and add the following:
And we're done! I tested this code as I wrote this answer, feel free to ask follow up questions if you have any.