You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:43:20