Quick tip of the day. Default Laravel Auth comes with User table and model, but without logging capability, so we need to build it ourselves. Fortunately, it’s very easy, I will show you one method.
Let’s say that we want to save user’s last login time and IP address in the same users table.
So we start with database migration:
php artisan make:migration add_login_fields_to_users_table
Then we fill it with these fields:
class AddLoginFieldsToUsersTable extends Migration { public function up() { Schema::table('users', function (Blueprint $table) { $table->datetime('last_login_at')->nullable(); $table->string('last_login_ip')->nullable(); }); } // ...
Next, we need to add these fields as fillables in app/User.php model:
class User extends Authenticatable { protected $fillable = [ 'email', 'password', 'name', 'last_login_at', 'last_login_ip', ]; // ...
Finally, how do we fill them in? You need to know that there is authenticated() method in the AuthenticatesUsers trait. It’s called every time someone logs in.
/** * The user has been authenticated. * * @param \Illuminate\Http\Request $request * @param mixed $user * @return mixed */ protected function authenticated(Request $request, $user) { // }
In trait this method is empty. So we have freedom to override it in LoginController and add whatever code we need.
app/Http/Controllers/Auth/LoginController.php:
function authenticated(Request $request, $user) { $user->update([ 'last_login_at' => Carbon::now()->toDateTimeString(), 'last_login_ip' => $request->getClientIp() ]); }
And, that’s it! Here’s what we have in users table after log in:
Do I have to set last_login_at as protected $dates?
Depends on how you use it later, if you want it to be used as Carbon object by default, then yes.
What other things may be interesting to collect that you could collect on Login? I really like this! Thank you!
You can collect anything that comes within Request class, or maybe even build some custom logic here. It’s pretty flexible.
When a password reset is performed the user is automatically logged in. This method is then not triggered. An event listener is maybe a better solution or what do you think?
Hi Leslie, same thing about registering – user is automatically logged in and this event isn’t triggered. Perhaps you’re right, even listener somewhere “deeper” could be better but you need to know what events to listen to.
hi, how could we get user browser/device data?
Hi, for that I would recommend this package: https://github.com/jenssegers/agent
I hope you guys noticed that the updated_at column gets the same value always as last_login_at column. It shouldn’t be so.
updated_at column should be different to last_login_at when you change your password or another personal data under users table.
hello sir..
i got current login IP
but i want last login IP
Havent’t tried this but what happens if the user just doesn’t logout instead just closed the browser or tab?
This was helpful, however as of Laravel 5.8.11 this code throws an error since Request is not an instance of Auth\Request.
Anyway, if you want just to save the login and not trigger the updated_at filed, just do :
function authenticated()
{
DB::table(‘users’)->where(‘id’, Auth::user()->id)->update([‘last_login_at’=>Carbon::now()->toDateTimeString()]);
}
Or you can add use Illuminate\Html\Request; on top.
You can, still for me it does not work proprerly – field does not get updated. First time I’v tried it, since it relies on the User model, it updated also the updated_at field, which is a undesirable side effect. DB interface do it properly. Or I’m missing something
Probably you’re missing something, it worked for me and many others. But maybe something changed in Laravel 5.7/5.8. Anyway, if DB interface works for you, great.
Kyobul, you should disable the timestamp like this to avoid updating the updated_at field-
$user->timestamps = false;
$user->last_login_at = Carbon::now()->toDateTimeString();
$user->last_login_ip = $request->getClientIp();
$user->save();
Thanks Pankaj for sharing how to suppress timestamps for User records. That fixes the problem.
is it possible in localhost(apache server only )
Hello sir, i know question is not related to this topic but I am new and I need help here. I have a column in a database table which I want to sum up the values in laravel. I don’t know what how to do that. Pls, if you can help
A quick tweak for users on Laravel 5.8 +
function authenticated(\Illuminate\Http\Request $request, $user)
{
$user->timestamps = false;
$user->last_login_at = Carbon::now()->toDateTimeString();
$user->last_login_ip = $request->ip();
$user->save();
}
This will also prevent the database from updating the ‘updated_at’ column.
The now function creates a new Illuminate\Support\Carbon instance for the current time.
This works for Laravel 7
function authenticated(\Illuminate\Http\Request $request, $user)
{
$user->timestamps = false;
$user->last_login_at = now();
$user->last_login_ip = $request->ip();
$user->save();
}
Hello, thanks for the tip. I’m wondering if this method is the right approach… Could an update to the framework/auth file break this change?
I have an quer to insert data when the user login / logout.
Regards
Hi Helder,
Updates to framework shouldn’t break it, because we’re not dealing with internal framework files in /vendor folder. A lot of customization to Auth are happening in LoginController like this, see more in this article: https://laraveldaily.com/9-things-you-can-customize-in-laravel-registration/
Hi, thank you 😉
Hi, thanks for sharing.
But what if we want to show the last login time somewhere in a view?
Wouldn’t it always shows the current login session and not the previous login just before the current login?
Yes, the article is about LAST login, and not the full history.
I take it authenticated() and loggedOut() are a part of the default auth setup for Laravel? I’ve been struggling for days to find the equivalent to these 2 methods in Laravel Passport, but no luck so far.
Hi, so if cookie lifetime is not expired and user no need require login, so this event trigger or not?
Hi, Povilas Korop
Nice article. If i want to get logout time then ? how i will do this stuff ?
These days people rarely log out of any websites, they just stay in and close the browser. So you can’t catch that browser close event in Laravel.
Hi, Povilas Korop
It’s working perfect in DB.
But else I in Index.blade {{$user->last_login_at->format(‘d/m/Y H:i’)}} then a error.
ErrorException (E_ERROR)
Call to a member function format() on string but in table is colomn datetime format.
Do you have a suggestion?
You need to add last_login_at to $dates in User model.
Read more: https://laravel.com/docs/7.x/eloquent-mutators#date-mutators
Yes, it works
What if the user checks “Remember me”, will this function ever be re-triggered when they come back?
I did the same but nothing happened. last login didn’t update. I am using laravel version 7.
To also insert the last login time and ip on user creation just extend the create function in Auth/RegisterController
I did it this way
protected function create(array $data)
{
$user = User::create([
‘name’ => $data[‘name’],
’email’ => $data[’email’],
‘password’ => Hash::make($data[‘password’]),
‘last_login_at’ => Carbon::now(‘Europe/Copenhagen’),
‘last_login_ip’ => \Request::Ip(),
]);
return $user;
}
I’m missing the ‘down’ function in the migration file. And also an hint to actual run the migration, for the absolute beginners it could be helpful.