最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Session keeps renewing when checking the status - Stack Overflow

programmeradmin9浏览0评论

In my laravel/inertia/vue application I'd like to check if the session is expired or not. If the session has expired, a popup should be displayed. The check is done by making a call to the backend. I'm using the session database driver.

In the backend - as a matter of fact, it will be moved to a controller if working accordingly:

Route::get('/session-status', function (\Illuminate\Http\Request $request) {
    $sessionId = cookie(config('session.cookie'));

    if (!\Illuminate\Support\Facades\Auth::check()) {
        return response()->json(['session_expired' => true], 401);
    }

    // Fetch session directly from the database (without updating last_activity)
    $sessionId = $request->session()->getId();
    $session = \Illuminate\Support\Facades\DB::table('sessions')
        ->select('last_activity')
        ->where('id', $sessionId)
        ->first();

    if ($session) {
        $sessionLifetime = config('session.lifetime') * 60;
        $sessionAge = now()->timestamp - $session->last_activity;

        if ($sessionAge > $sessionLifetime) {
            return response()->json(['session_expired' => true], 401);
        }
    }

    return response()->json(['session_expired' => false]);
})->name('session.status');

In the frontend a simple axios call is made:

const showPopup = ref(false);

const checkSession = async () => {
    try {
        await axios.get('/api/session-status');
    } catch (error) {
        if (error.response && error.response.status === 401) {
            showPopup.value = true;
        }
    }
};

// Run session check every 1 minute
onMounted(() => {
    setInterval(checkSession, 6000);
});

I've tried many many options, but laravel keeps on renewing the session if the session is still active. This is nice behaviour when working in the application, but undesired for just checking the session status, as it creates a "drip" keeping the session alive forever.

Anybody a solution?

In my laravel/inertia/vue application I'd like to check if the session is expired or not. If the session has expired, a popup should be displayed. The check is done by making a call to the backend. I'm using the session database driver.

In the backend - as a matter of fact, it will be moved to a controller if working accordingly:

Route::get('/session-status', function (\Illuminate\Http\Request $request) {
    $sessionId = cookie(config('session.cookie'));

    if (!\Illuminate\Support\Facades\Auth::check()) {
        return response()->json(['session_expired' => true], 401);
    }

    // Fetch session directly from the database (without updating last_activity)
    $sessionId = $request->session()->getId();
    $session = \Illuminate\Support\Facades\DB::table('sessions')
        ->select('last_activity')
        ->where('id', $sessionId)
        ->first();

    if ($session) {
        $sessionLifetime = config('session.lifetime') * 60;
        $sessionAge = now()->timestamp - $session->last_activity;

        if ($sessionAge > $sessionLifetime) {
            return response()->json(['session_expired' => true], 401);
        }
    }

    return response()->json(['session_expired' => false]);
})->name('session.status');

In the frontend a simple axios call is made:

const showPopup = ref(false);

const checkSession = async () => {
    try {
        await axios.get('/api/session-status');
    } catch (error) {
        if (error.response && error.response.status === 401) {
            showPopup.value = true;
        }
    }
};

// Run session check every 1 minute
onMounted(() => {
    setInterval(checkSession, 6000);
});

I've tried many many options, but laravel keeps on renewing the session if the session is still active. This is nice behaviour when working in the application, but undesired for just checking the session status, as it creates a "drip" keeping the session alive forever.

Anybody a solution?

Share Improve this question edited Feb 5 at 10:03 DarkBee 15.6k8 gold badges71 silver badges116 bronze badges asked Feb 5 at 8:48 Jan-WillemJan-Willem 117 bronze badges 2
  • I think your main issue is that you are using Auth::check(), what happens if you use Auth::id()? Does it also change the last_activity? – matiaslauriti Commented Feb 5 at 13:43
  • Yes practically everything is refreshing the session, except for dumping the data with dd() but that't not the way to go :-) Tried it without the Auth::check aswell. – Jan-Willem Commented Feb 6 at 9:38
Add a comment  | 

1 Answer 1

Reset to default 2

What you can do is you can create middleware because of which your session will not get inadvertently be live. As here whenever you checks the session it will keep it alive. As sessions are timeout when they are not used for particular period of time.

First create middleware

php artisan make:middleware CheckSession

Implement your whole logic like below

 namespace App\Http\Middleware;

 use Closure;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;

 class CheckSession
 {
     public function handle($request, Closure $next)
     {
         if (!Auth::check()) {
             return response()->json(['session_expired' => true], 401);
         }

         $sessionId = $request->session()->getId();
         $session = DB::table('sessions')->select('last_activity')->where('id', $sessionId)->first();

         if ($session) {
             $sessionLifetime = config('session.lifetime') * 60;
             $sessionAge = now()->timestamp - $session->last_activity;

             if ($sessionAge > $sessionLifetime) {
                 return response()->json(['session_expired' => true], 401);
             }
         }

         return $next($request);
     }
 }

Now register your Middleware in 'app/Http/Kernel.php'

protected $routeMiddleware = [
    // ...
    'check.session' => \App\Http\Middleware\CheckSession::class,
];

Now your route

Route::get('/session-status', function () {
    return response()->json(['session_expired' => false]);
})->middleware('check.session')->name('session.status');

I hope this should work.

发布评论

评论列表(0)

  1. 暂无评论