Track your users last activity in Laravel
Although there's many ways to do this in Laravel, the simplest way is with a piece of web middleware.
The setup
When an authenticated user visits a route in our application, we want to store the timestamp in the database for use later on. Let's store it in a column called last_active_at.
All you need to do is create a migration:
php artisan make:migration add_last_active_at_to_users_table --table=users
And add the following line in the up() method:
$table->timestamp('last_active_at')->nullable();
If the user has never visited a route, it will remain NULL in the database.
We also want to make sure this field is "fillable", so add last_active_at to the protected $fillable array on your User model.
As well as being able to update last_active_at using User::update(), we want to cast it to a Carbon\Carbon instance when using it so that we can make use of time comparison methods.
The middleware
Logic
The middleware will be responsible for checking the authentication status and updating the last_active_at column.
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Closure;
class TrackLastActiveAt
{
public function handle(Request $request, Closure $next)
{
if (! $request->user()) {
return $next($request);
}
if (! $request->user()->last_active_at || $request->user()->last_active_at->isPast()) {
$request->user()->update([
'last_active_at' => now(),
]);
}
return $next($request);
}
}
Here's what happens in order:
- We check the current user is authenticated. If they're not, we're returning early so that the rest of the middleware has no effect.
- If the current user
last_active_atdate & time isNULLor is in the past, we want to update it using the current date and time. Thankfully, Laravel has anow()helper function that returns an instance ofCarbon\Carbonfor the current date and time. - Forward the current request on to the next middleware.
Registration
We have a couple of different options for registering the middleware. If you want to track your users activity across all routes, it should be registered under the web array in App\Http\Kernel:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\TrackLastActiveAt::class,
]
]
If you only want to track the latest activity for particular routes, you can register the middleware as part of your route registration:
Route::get('/foo', 'FooController')->middleware([\App\Http\Middleware\TrackLastActiveAt::class]);