Files
laravel-nuxt-ui-inertia-tem…/app/Http/Middleware/EnforceAbsoluteSessionTimeout.php

83 lines
2.3 KiB
PHP

<?php
namespace App\Http\Middleware;
use App\Models\User;
use App\Services\Auth\SecurityEventRecorder;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class EnforceAbsoluteSessionTimeout
{
public function __construct(
private readonly SecurityEventRecorder $securityEvents
) {}
public function handle(Request $request, Closure $next): Response
{
if (! $request->user() || ! $request->hasSession()) {
return $next($request);
}
/** @var User $user */
$user = $request->user();
$sessionVersion = $request->session()->get('auth.session_version');
$userVersion = (int) $user->auth_session_version;
if (! is_int($sessionVersion) && $userVersion === 0) {
$request->session()->put('auth.session_version', 0);
} elseif ($sessionVersion !== $userVersion) {
return $this->terminateSession(
$request,
$user,
'session.revoked',
'Your session is no longer valid. Please sign in again.'
);
}
$expiresAt = $request->session()->get('auth.absolute_expires_at');
if (! is_int($expiresAt)) {
$request->session()->put(
'auth.absolute_expires_at',
now()->timestamp + config('auth-ui.security.absolute_session_lifetime')
);
return $next($request);
}
if (now()->timestamp < $expiresAt) {
return $next($request);
}
return $this->terminateSession(
$request,
$user,
'session.absolute_timeout',
'Your session has expired. Please sign in again.'
);
}
private function terminateSession(
Request $request,
User $user,
string $event,
string $message
): Response {
$this->securityEvents->record($event, $user, $request);
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($request->expectsJson()) {
return response()->json(['message' => $message], 401);
}
return redirect()->route('login')
->with('error', $message);
}
}