hasSession()) { return $response; } $uuid = $request->session()->get(LoginSession::KEY); if (! is_string($uuid) || $uuid === '') { return $response; } $current = $request->session()->getId(); // A bare update rather than a model round-trip: this is on the path of // every authenticated request, and the row is not needed, only moved. DB::table('login_sessions') ->where('uuid', $uuid) ->where(function ($q) use ($current) { // A CHANGED id is never throttled. Both sign-in paths raise the // Login event before calling session()->regenerate(), so the row // is written against an id that is dead a moment later. Held // back by the throttle, the row would point at nothing for the // first minute of every session — the one it describes missing // from the list, and "end this one" deleting a session that no // longer exists. $q->where('session_id', '!=', $current) ->orWhereNull('session_id') ->orWhereNull('last_seen_at') ->orWhere('last_seen_at', '<=', now()->subSeconds(self::THROTTLE_SECONDS)); }) ->update([ 'session_id' => $current, 'ip_address' => $request->ip(), 'last_seen_at' => now(), 'updated_at' => now(), ]); return $response; } }