How to record the last login (online) time of a user?
The user table has created_at and updated_at fields.
I want to add a logged_at field. To track when the user was last on the site. How to do this using Laravel and Filament?
Or how to do it correctly?
34 Replies
This is not really filament specific, this page should get you going
https://laraveldaily.com/post/save-users-last-login-time-ip-address
Laravel Daily
How to Save User's Last Login Time and IP Address
Is there a plugin where the history of logins (time, IP, location, etc.) and active sessions is stored?
certainly
Filament
Plugins - Filament
Community made packages for Filament projects, which give you access to awesome new features.
Which one do you recommend?
Oh i have not used one myself
just pick one you like
How do I add the logic of updating the last_login_at and last_login_ip fields to the Filament?
Where can I do this?
You dont need filament for that
Listen for the authenicated event and do your logic
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
It's still hard for me to figure it out. Could you tell me which file to add the code to:
$user->update([
'last_login_at' => Carbon::now()->toDateTimeString(),
'last_login_ip' => $request->getClientIp()
]);
You can create a new class
php artisan make:listener LogSuccessfulLogin
that class will have a handle($event) method where you can put the logic
Will it work after registration too?
that is a different event
so you should listen for a different one
but if you log in directly after registration
it should be fine
It is necessary that both after login and after registration the data is recorded in the fields
?
i have provided you the answers, just take the time to read the documentation
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
laravel has a Registered event you can listen for
Thanks
And which event is responsible for visiting the site? I want to update these fields not only when login and registration, but also when the user was last on the site. To record the last visit. What kind of event is this?
use middleware for that
instead of an event
middleware gets executed every request
i implented it with middleware that sets a current timestamp on the user (new column: last_activity for example). Then I check whether the last actitvity is older than 5 minutes to display whether the user is "online" or "idle" and cache the result.
On the User Model you then can check for the key in the cache with the user id. if it exists, the user is online like so:
/**
* @return bool
*/
public function isOnline() : bool {
return Cache::has('user-is-online-' . $this->id);
}
a better way for this though are websockets and presense channels!
Thank you. In this case, how can you find out what time you were last active? For example, the last_active_at field in the users table. Where and when should I fill out this field?
I think we need to overwrite the last_active_at field in the middleware. And in the isOnline model, if more than 5 minutes have passed since last_active_at, then the user is not active. For example.
But what to do if the user has a tab open in the browser. And he's online. But this solution will not show that it is online, because the page is not updated.
a solution would be a little javascript on the page
that just sends a heartbeat to the server every X seconds
There is no "isOnline" model. "isOnline" is a method on the User Model. And the last active timestamp is set on every request that the user makes, because it is set in the middleware... you only need to register the middleware in your web stack....
Yes, I mean the isOnline method. Using the cache for 5 minutes, I won't be able to know the exact time of the user's last activity. For example, it was active 1 or 2 days ago. Therefore, the timestamp must be stored in the database.
If you really want a "correct" implementation (user is set to offline, once he closes the browser) you would need to do it with websockets and presense channels, as stated before in my first answer...
well... the last activity timestamp will contain the timestamp of the last activity, which can be 1 or 2 days old...
But in your screenshot it uses the cache. If it gets destroyed, I won't be able to find out the timestamp.
sorry - you are absolutely right. i switched to cache because i only needed the info whether the user is online or not. But you could just exchange cache for a column on the user table. I think i mentioned this in my initial answer.... maybe it was a bit confusing, because i mixed up the implementations ^^
add a last_activty column to the user table, then in the middleware you udate the timestamp in the db for the currently logged in user (or you get the user object from the request) and on the user model you dont check the cache, but instead just check whether the TS is older than x minutes to return true/false
middleware: update last_active_at in user table
model user, method isOnline: if ($now - $...->last_active_at) < 5 min then user is online else is not online
excatly
Where should I connect middleware LastUserActivity? In App\Http\Kernel.php or in App\Providers\Filament\AdminPanelProvider.php ?
depends where you want to use it. if you only need it on the filament part, i would add it to the panel...
if you also want to use it outside of filament, you can add it to the kernel
If I add it to the kernel, then will it work globally, including in the Filament?
try it. but i think you need to add it to the panel...