如何在Laravel中记录用户登出时间至数据库
在Laravel中记录用户登出时间的两种常用方案
首先确保你的用户表(默认是users)有logout_at字段,如果没有,先创建迁移:
php artisan make:migration add_logout_at_to_users_table --table=users
然后在生成的迁移文件中添加字段定义:
public function up() { Schema::table('users', function (Blueprint $table) { $table->timestamp('logout_at')->nullable(); }); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('logout_at'); }); }
执行迁移生效:
php artisan migrate
方案一:监听Laravel自带的Logout事件
Laravel在用户主动登出时会触发Illuminate\Auth\Events\Logout事件,通过监听这个事件可以自动记录登出时间:
- 生成事件监听器:
php artisan make:listener LogLogoutTime --event=Illuminate\Auth\Events\Logout
- 打开生成的
app/Listeners/LogLogoutTime.php,修改handle方法:
public function handle(Logout $event) { // $event->user 即为当前登出的用户实例 $event->user->update([ 'logout_at' => now() ]); }
- 在
app/Providers/EventServiceProvider.php的$listen数组中注册事件与监听器的关联:
protected $listen = [ // 保留其他已注册事件 \Illuminate\Auth\Events\Logout::class => [ \App\Listeners\LogLogoutTime::class, ], ];
完成后,用户每次主动登出时,系统会自动更新logout_at字段。
方案二:重写Auth控制器的登出方法
如果你不想用事件监听,也可以直接重写Auth控制器的登出逻辑:
Laravel 8+ 版本(对应AuthenticatedSessionController)
use Illuminate\Http\Request; public function destroy(Request $request) { // 先获取用户实例,登出后无法再通过auth()->user()获取 $user = $request->user(); // 执行框架默认的登出逻辑 $this->guard()->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); // 更新登出时间 if ($user) { $user->update([ 'logout_at' => now() ]); } return redirect('/'); }
Laravel 5.x/6.x 版本(对应LoginController)
use Illuminate\Http\Request; public function logout(Request $request) { $user = $request->user(); $this->guard()->logout(); $request->session()->invalidate(); if ($user) { $user->update([ 'logout_at' => now() ]); } return redirect('/'); }
额外说明:处理会话自动过期的情况
上面的方案仅覆盖用户主动登出的场景,如果需要记录会话自动过期的时间,可以通过中间件实现近似记录:
- 生成中间件:
php artisan make:middleware RecordSessionExpiry
- 在中间件的
handle方法中添加逻辑:
use Carbon\Carbon; public function handle(Request $request, Closure $next) { $response = $next($request); // 检查用户已认证且会话已过期 if (auth()->check() && $request->session()->has('last_activity')) { $lastActivity = Carbon::parse($request->session()->get('last_activity')); if (now()->diffInMinutes($lastActivity) >= config('session.lifetime')) { auth()->user()->update([ 'logout_at' => now() ]); } } // 更新用户最后活跃时间 $request->session()->put('last_activity', now()); return $response; }
- 在
app/Http/Kernel.php的web中间件组中注册该中间件:
protected $middlewareGroups = [ 'web' => [ // 保留其他已注册中间件 \App\Http\Middleware\RecordSessionExpiry::class, ], ];
注意:这种方式是基于用户最后一次请求的时间推算过期时间,记录的时间会和实际过期时间有微小偏差。
内容的提问来源于stack exchange,提问作者archibaldenko
相关产品推荐
相关产品推荐

