Laravel 10双条件会话超时设置:控制最大登录时长
Laravel 10 双条件会话超时实现方案
针对你提出的两个会话超时需求,Laravel 默认只支持无活动超时(即SESSION_LIFETIME配置),强制超时需要自行实现,以下是具体步骤:
1. 保留无活动超时配置
你已经在.env中设置SESSION_LIFETIME=30,这个配置会自动处理30分钟无活动则会话超时的需求——Laravel 会在用户每次发起请求时刷新会话 cookie 的过期时间,只要用户30分钟内没操作,cookie 就会失效,会话自动终止。
2. 实现1小时强制超时
需要通过「存储登录时间 + 中间件校验」的方式实现:
步骤一:存储用户登录时间
在用户登录成功后,把当前时间戳存入会话。
- 如果你用的是 Laravel 自带的登录控制器(比如
LoginController),可以重写authenticated方法:
protected function authenticated(Request $request, $user) { session(['login_at' => now()->timestamp]); }
- 如果你用的是 Breeze/Fortify 等认证包,找到登录成功后的回调钩子,添加上述会话存储逻辑即可。
步骤二:创建自定义校验中间件
生成一个中间件用于每次请求时检查是否超过强制超时时间:
php artisan make:middleware CheckSessionExpiration
打开生成的app/Http/Middleware/CheckSessionExpiration.php,编写校验逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class CheckSessionExpiration { public function handle(Request $request, Closure $next) { // 仅对已登录用户进行校验 if (Auth::check()) { $loginTimestamp = session('login_at'); // 兼容未设置登录时间的历史会话,默认存入当前时间 if (!$loginTimestamp) { session(['login_at' => now()->timestamp]); return $next($request); } // 计算已登录时长,超过3600秒(1小时)则强制登出 if (now()->timestamp - $loginTimestamp > 3600) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect()->route('login')->with('message', '会话已超时,请重新登录'); } } return $next($request); } }
步骤三:注册中间件
打开app/Http/Kernel.php,将上述中间件添加到web中间件组中,注意要放在StartSession中间件之后:
protected $middlewareGroups = [ 'web' => [ // ...其他已有中间件 \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\CheckSessionExpiration::class, // 新增这一行 // ...其他已有中间件 ], ];
注意事项
- 由于你使用 cookie 会话驱动,会话数据会被 Laravel 自动加密签名存储在客户端 cookie 中,用户无法篡改
login_at的值,安全性有保障。 - 如果需要调整强制超时的时长,直接修改中间件中的
3600为对应秒数即可。
内容的提问来源于stack exchange,提问作者Harshit Aggarwal
相关产品推荐
相关产品推荐

