如何配置Laravel避免自动延长认证会话并强制其到期?
这个问题我之前也折腾过,Laravel默认的会话机制确实是每次用户发起请求就自动续期,要实现「不管用不用都到点过期」的效果,得从会话的过期逻辑入手,下面给你两个可行的方案,按需选就行:
方案一:登录时设置固定会话过期时间(推荐)
这种方法针对性强,只对用户登录后的会话生效,逻辑也更清晰。
- 找到你的登录控制器(默认是
app/Http/Controllers/Auth/LoginController.php),如果没有authenticated方法,就新增一个:
protected function authenticated(Request $request, $user) { // 获取配置文件里的会话有效期(分钟) $lifetime = config('session.lifetime'); // 计算固定过期时间:当前时间 + 设定的有效期 $expireAt = now()->addMinutes($lifetime); // 把过期时间存入会话 $request->session()->put('expire_at', $expireAt->timestamp); }
- 创建一个专门检查会话过期的中间件:
php artisan make:middleware CheckSessionExpiration
- 打开生成的
app/Http/Middleware/CheckSessionExpiration.php,修改handle方法:
use Carbon\Carbon; use Illuminate\Support\Facades\Auth; public function handle(Request $request, Closure $next) { if ($request->session()->has('expire_at')) { $expireAt = Carbon::createFromTimestamp($request->session()->get('expire_at')); // 如果当前时间已超过过期时间,强制登出并销毁会话 if (now()->gte($expireAt)) { 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' => [ // ...其他中间件 \App\Http\Middleware\StartSession::class, \App\Http\Middleware\CheckSessionExpiration::class, // ...其他中间件 ], ];
这样用户登录后,会话就有了固定的过期时间,不管之后有没有操作,到点都会被强制登出。
方案二:全局禁用会话自动续期
如果想要所有会话(包括未登录用户的会话)都遵循固定过期规则,可以用这个方法:
- 先修改
config/session.php的基础配置:
return [ // ...其他配置 'lifetime' => 120, // 你想要的固定有效期(分钟) 'expire_on_close' => false, ];
- 自定义
StartSession中间件,重写会话续期逻辑:
创建app/Http/Middleware/StartSession.php,继承框架的原中间件:
namespace App\Http\Middleware; use Illuminate\Session\Middleware\StartSession as BaseStartSession; class StartSession extends BaseStartSession { // 重写刷新会话过期时间的方法,直接空实现 protected function refreshSessionExpiration($request) { // 注释掉父类的自动续期逻辑,让会话过期时间不再随请求刷新 // parent::refreshSessionExpiration($request); } }
- 在
app/Http/Kernel.php里替换原有的StartSession中间件:
protected $middlewareGroups = [ 'web' => [ // ...其他中间件 // \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\StartSession::class, // ...其他中间件 ], ];
修改后,所有会话的过期时间都是创建时的时间加上lifetime,不会因为后续请求延长,到点自动失效。
注意事项
- 如果你用的是
database或redis会话驱动,要确保存储介质的过期时间和配置同步; - 测试时可以把
lifetime设为1分钟,快速验证效果; - 方案一适合仅针对登录用户会话的场景,方案二更适合全局会话管控。
内容的提问来源于stack exchange,提问作者Alexey Alshenetsky
相关产品推荐
相关产品推荐

