F
Filament3mo ago
WEBMAS

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
Patrick1989
Patrick19893mo ago
This is not really filament specific, this page should get you going https://laraveldaily.com/post/save-users-last-login-time-ip-address
WEBMAS
WEBMAS3mo ago
Is there a plugin where the history of logins (time, IP, location, etc.) and active sessions is stored?
Patrick1989
Patrick19893mo ago
certainly
Patrick1989
Patrick19893mo ago
Filament
Plugins - Filament
Community made packages for Filament projects, which give you access to awesome new features.
WEBMAS
WEBMAS3mo ago
Which one do you recommend?
Patrick1989
Patrick19893mo ago
Oh i have not used one myself just pick one you like
WEBMAS
WEBMAS3mo ago
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?
Patrick1989
Patrick19893mo ago
You dont need filament for that Listen for the authenicated event and do your logic
Patrick1989
Patrick19893mo ago
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.
Patrick1989
Patrick19893mo ago
No description
WEBMAS
WEBMAS3mo ago
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() ]);
Patrick1989
Patrick19893mo ago
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
WEBMAS
WEBMAS3mo ago
Will it work after registration too?
Patrick1989
Patrick19893mo ago
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
WEBMAS
WEBMAS3mo ago
It is necessary that both after login and after registration the data is recorded in the fields ?
Patrick1989
Patrick19893mo ago
i have provided you the answers, just take the time to read the documentation
Patrick1989
Patrick19893mo ago
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.
Patrick1989
Patrick19893mo ago
laravel has a Registered event you can listen for
WEBMAS
WEBMAS3mo ago
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?
Patrick1989
Patrick19893mo ago
use middleware for that instead of an event middleware gets executed every request
SiGuy
SiGuy3mo ago
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!
No description
WEBMAS
WEBMAS3mo ago
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.
Patrick1989
Patrick19893mo ago
a solution would be a little javascript on the page that just sends a heartbeat to the server every X seconds
SiGuy
SiGuy3mo ago
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....
WEBMAS
WEBMAS3mo ago
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.
SiGuy
SiGuy3mo ago
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...
WEBMAS
WEBMAS3mo ago
But in your screenshot it uses the cache. If it gets destroyed, I won't be able to find out the timestamp.
SiGuy
SiGuy3mo ago
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
WEBMAS
WEBMAS3mo ago
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
SiGuy
SiGuy3mo ago
excatly
WEBMAS
WEBMAS3mo ago
Where should I connect middleware LastUserActivity? In App\Http\Kernel.php or in App\Providers\Filament\AdminPanelProvider.php ?
No description
No description
SiGuy
SiGuy3mo ago
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
WEBMAS
WEBMAS3mo ago
If I add it to the kernel, then will it work globally, including in the Filament?
SiGuy
SiGuy3mo ago
try it. but i think you need to add it to the panel...