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

Laravel 9会话超时后无法触发重定向逻辑问题求助

问题分析

你的中间件超时判断逻辑从未执行,核心原因是Laravel自带的会话过期机制会先于你的中间件销毁会话:当用户长时间无操作,Laravel的StartSession中间件会检测到会话过期并清空会话数据,此时Auth::check()返回false,导致你的超时判断if块永远无法触发。你看到的自动登出是Laravel的Authenticate中间件检测到未登录后触发的跳转,而非你的中间件逻辑。

解决方案

1. 调整中间件执行顺序

在app/Http/Kernel.php的web中间件组中,将CheckSessionTimeout放在StartSession之后、Authenticate之前,确保在Laravel自动销毁会话前,你的中间件能先检查空闲时间:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \App\Http\Middleware\CheckSessionTimeout::class, // 新增位置
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

2. 修改中间件逻辑

优化代码逻辑,确保在会话未被Laravel销毁前检测空闲超时,并手动控制登出与跳转:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CheckSessionTimeout
{
    public function handle($request, Closure $next)
    {
        // 仅对已登录用户处理
        if (Auth::check()) {
            $maxIdleTime = config('session.lifetime') * 60;
            // 读取最后活动时间,默认值为当前时间(首次登录时)
            $lastActivity = $request->session()->get('lastActivityTime', time());

            // 判断是否超过空闲时间
            if (time() - $lastActivity > $maxIdleTime) {
                // 设置会话超时标记
                $request->session()->put('sessionTimedOut', true);
                // 手动登出用户
                Auth::logout();
                // 销毁当前会话并生成新的CSRF令牌
                $request->session()->invalidate();
                $request->session()->regenerateToken();
                // 跳转到登录页,可自定义提示信息
                return redirect()->route('login')->with('error', '会话已超时,请重新登录');
            }

            // 更新最后活动时间
            $request->session()->put('lastActivityTime', time());
        }

        return $next($request);
    }
}

3. 测试验证

临时缩短会话生命周期来快速测试:在.env文件中设置SESSION_LIFETIME=1(表示1分钟超时),登录后等待1分钟再操作,就能触发你的中间件逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:32:45