Laravel 9.52中如何记录用户活跃时长及会话结束类型
Laravel 9 实现登录/登出/会话超时日志记录及活跃时长统计
一、记录登录与主动登出事件
先完善EventServiceProvider,添加登录事件监听,同时优化主动登出的日志记录,加入活跃时长计算:
public function boot() { // 主动登出事件监听 Event::listen(\Illuminate\Auth\Events\Logout::class, function ($event) { if(Auth::check()) { $activeDuration = now()->diffInSeconds(session('login_at')); Activity::create([ 'log_name' => 'auth', 'description' => '主动退出', 'causer_id' => Auth::id(), 'properties' => [ 'active_duration' => $activeDuration ] ]); session()->forget('login_at'); } }); // 登录事件监听 Event::listen(\Illuminate\Auth\Events\Login::class, function ($event) { session(['login_at' => now()]); Activity::create([ 'log_name' => 'auth', 'description' => '登录', 'causer_id' => $event->user->id ]); }); }
二、处理会话超时/被动登出
Laravel无法直接监听会话超时事件,需结合数据库会话驱动和定时任务实现:
1. 切换到数据库会话驱动
修改.env配置:
SESSION_DRIVER=database
生成并执行会话表迁移:
php artisan session:table php artisan migrate
2. 创建清理过期会话的命令
生成自定义命令:
php artisan make:command CleanExpiredSessions
编辑app/Console/Commands/CleanExpiredSessions.php:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; use Carbon\Carbon; class CleanExpiredSessions extends Command { protected $signature = 'session:clean-expired'; protected $description = '清理过期会话并记录被动登出日志'; public function handle() { $expiredTime = Carbon::now()->subMinutes(config('session.lifetime'))->timestamp; $expiredSessions = DB::table('sessions') ->where('last_activity', '<=', $expiredTime) ->whereNotNull('user_id') ->get(); foreach ($expiredSessions as $session) { $sessionData = unserialize(base64_decode($session->payload)); $loginAt = isset($sessionData['login_at']) ? Carbon::parse($sessionData['login_at']) : null; Activity::create([ 'log_name' => 'auth', 'description' => '系统踢除(会话超时)', 'causer_id' => $session->user_id, 'properties' => [ 'active_duration' => $loginAt ? Carbon::now()->diffInSeconds($loginAt) : null ] ]); } $this->call('session:clear'); $this->info('已清理过期会话并记录被动登出日志'); } }
3. 注册定时任务
在app/Console/Kernel.php的schedule方法中添加:
protected function schedule(Schedule $schedule) { // 每分钟执行一次,可根据业务调整频率 $schedule->command('session:clean-expired')->everyMinute(); }
三、注意事项
- 确保
Activity模型的properties字段为json类型,用于存储活跃时长等扩展数据。 - 服务器需配置Laravel任务调度器(通过
cron),保证定时任务正常运行。 - 若使用Redis会话驱动,可调整命令中的会话查询逻辑,适配Redis存储结构。
内容的提问来源于stack exchange,提问作者Poria
相关产品推荐
相关产品推荐

