Although there's many ways to do this in Laravel, the simplest way is with a piece of web
middleware.
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 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:
last_active_at
date & time is NULL
or is in the past, we want to update it using the current date and time. Thankfully, Laravel has a now()
helper function that returns an instance of Carbon\Carbon
for the current date and time.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]);