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

Laravel用户最后活动时间追踪及自动登出问题排查

问题解答

问题1:auth路由组内执行操作时,session的activity_time是否会更新?

会更新。因为你的Authenticate中间件是auth路由组绑定的核心中间件,每次访问该组内的路由时,都会触发中间件的handle方法:

  • 已登录用户的auth()->check()会返回true,因此会执行session()->put('activity_time', now()->toDateTimeString()),覆盖旧的session值。
  • 只要请求进入auth路由组,这个更新逻辑就会触发,所以每次操作都会刷新最后活动时间。

问题2:CheckLastActivityTime中间件中$lastActivity为null的原因及解决方案

原因分析

你把CheckLastActivityTime注册到了全局$middleware数组中,但Laravel的全局中间件执行顺序早于StartSession中间件(负责加载和初始化session)。当该中间件运行时,session还未启动,自然无法获取到activity_time的值,所以返回null。

正确实现步骤

1. 调整中间件注册位置

将CheckLastActivityTime从全局$middleware移到web中间件组,且放在StartSession和Authenticate之后,确保session已加载、用户身份已验证:

// app/Http/Kernel.php
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\Authenticate::class,
        \App\Http\Middleware\CheckLastActivityTime::class, // 移到此处
    ],
];

2. 拆分活动时间更新逻辑

不建议在Authenticate中间件中混入更新逻辑,新建一个UpdateActivityTime中间件专门处理活动时间刷新:

// app/Http/Middleware/UpdateActivityTime.php
<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class UpdateActivityTime
{
    public function handle(Request $request, Closure $next)
    {
        if (auth()->check()) {
            session()->put('activity_time', now()->toDateTimeString());
        }
        return $next($request);
    }
}

将其注册到web中间件组的CheckLastActivityTime之后(先检查超时,再更新最新时间,避免逻辑冲突):

// app/Http/Kernel.php -> web中间件组
\App\Http\Middleware\CheckLastActivityTime::class,
\App\Http\Middleware\UpdateActivityTime::class, // 新增

3. 修正CheckLastActivityTime中间件细节

补充未登录用户跳过检查、首次登录初始化时间的逻辑:

// app/Http/Middleware/CheckLastActivityTime.php
<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Carbon\Carbon;

class CheckLastActivityTime
{
    public function handle(Request $request, Closure $next)
    {
        // 未登录用户直接跳过
        if (!auth()->check()) {
            return $next($request);
        }

        $lastActivity = session()->get('activity_time');
        
        // 首次登录时初始化活动时间
        if (!$lastActivity) {
            session()->put('activity_time', now()->toDateTimeString());
            return $next($request);
        }

        $lastActivityTime = Carbon::parse($lastActivity);
        if (Carbon::now()->diffInMinutes($lastActivityTime) > 5) {
            auth()->logout();
            session()->invalidate();
            session()->regenerateToken();

            return redirect()->route('root')->with('error', '会话已过期,请重新登录。');
        }

        return $next($request);
    }
}

4. 确认路由中间件配置

确保Kernel.php的$routeMiddleware中存在auth绑定:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    // ... 其他中间件
];

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:10:19