Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

pavj888's avatar

Help is neededd on idle session time out

Hello Everyone,

I want to logout a user if he is idle for ten minutes. And display him a message before one minute that his session is going to expire. How should I do it in laravel.

Is there any way to do it in laravel. Please do help with this

thanks

0 likes
6 replies
RobinMalfait's avatar

use some javascript timer, if time is over, do a post request to the server to log him out...

accent-interactive's avatar
Level 14

Create a special expiration route that you poll through ajax on a regular interval.

  1. Create a middleware that sets the last active time and keeps track of whether you have already warned the user about expiration.
<?php

namespace App\Http\Middleware;

use Closure;
use Session;

class ResetLastActive
{

    public function handle($request, Closure $next)
    {
        Session::set('lastActive', date('U'));
        Session::forget('idleWarningDisplayed');
        Session::forget('logoutWarningDisplayed');

        return $next($request);
    }
}

Don't forget to register this middleware in app/Http/Kernel.php

'resetLastActive' => \App\Http\Middleware\ResetLastActive::class,
  1. Use this middleware on all routes that should reset the lastActive time.
Route::group(['middleware' => 'resetLastActive'], function () {
    Route::get('/', ['uses' => 'WelcomeController@index', 'as' => 'welcome']);
});

// This will be the route that checks expiration!
Route::post('session/ajaxCheck', ['uses' => 'SessionController@ajaxCheck', 'as' => 'session.ajax.check']);
  1. As you have seen, a route to check expiration has already been added to the routes file. Now, create a view partial that displays a warning if the user is about to be logged out, or refreshes the page if he was logged out. Call the session.ajax.check route we just created, maybe every 5 seconds or so.
<script>
    function checkSession() {
        $.post('{{ route('session.ajax.check') }}', { '_token' : '{!! csrf_token() !!}' }, function(data) {
            if (data == 'loggedOut') {
                // User was logged out. Redirect to login page
                document.location.href = '{!! route('login') !!}';
            }
            else if (data != '') {
                // User will be logged out soon. 
               // TODO display proper modal, instead of console.log()
                console.log(data);
            }
        });
    }
    setInterval(checkSession, 1000);
</script>

Create a controller and method for the session.ajax.check route. Have it return:

  • an empty string if all is well
  • a string containing a warning if the user will be logged out soon
  • a special logged out string if the user has been logged out.
<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use Illuminate\Http\Request;
use Session;

class SessionController extends Controller
{

    public function ajaxCheck()
    {
        /*
         * TODO abstract this logic away to the domain
         */

        // Configuration
        $maxIdleBeforeLogout = 10 * 1;
        $maxIdleBeforeWarning = 9 * 1;
        $warningTime = $maxIdleBeforeLogout - $maxIdleBeforeWarning;

        // Calculate the number of seconds since the use's last activity
        $idleTime = date('U') - Session::get('lastActive');

        // Warn user they will be logged out if idle for too long
        if ($idleTime > $maxIdleBeforeWarning && empty(Session::get('idleWarningDisplayed'))) {

            Session::set('idleWarningDisplayed', true);

            return 'You have ' . $warningTime . ' seconds left before you are logged out';
        }

        // Log out user if idle for too long
        if ($idleTime > $maxIdleBeforeLogout && empty(Session::get('logoutWarningDisplayed'))) {

            // *** Do stuff to log out user here

            Session::set('logoutWarningDisplayed', true);

            return 'loggedOut';
        }

        return '';
    }
}
5 likes
Snapey's avatar

Bear in mind that if you go down the JavaScript only route then you will only be able to timeout activity in the one window. If the user has two tabs open then they could be working away in one window and be timed out in the other. If as @malfait.robin suggests, you log the user out then they will be logged out on all windows and not just the one they had abandoned.

1 like
pavj888's avatar

First of all thank you everyone for quick reply.

@joostvanveen The answer is awesome . thank you very much .I will try it hope that works for me.But also I need to check the mouse and keypress activity for user to check whether he is idle for some time to display him a warning msg.

@ Snapey - yes I will.

thank you very much

accent-interactive's avatar

@pavj888 you're welcome. For that, create a simple javascript function that displays an idle warning message. Call that function using setTimeout. Simply reset the timer on keypress and click, or any other actions to your liking.

blbraner's avatar

Hey everyone just wanted to put this out there, I had to wrap the route for the controller in a middleware group for web and auth for this to properly get the session data in the ajaxCheck method in Laravel 5.2

Route::group(['middleware' => ['web', 'auth']], function () {
    Route::post('session/ajaxCheck', ['uses' => 'SessionController@ajaxCheck', 'as' => 'session.ajax.check']);
});

Please or to participate in this conversation.