Reputation: 4020
Bottom line:
How to logout the user on session time out?
Detailed Question:
I have a Laravel 5.6.* application and the project demands the user to logout whenever the user is idle. I have tried the solutions that are given here, but none of them worked for me.
Then I stumbled upon this post: https://laravel-tricks.com/tricks/session-timeout-for-logged-in-user and made my way through it to no success.
What I want:
Logout the user automatically on session timeout. Before logging out, set is_logged_in
attribute to false
or 0
on the Users
table. How do I achieve this?
Code that I have tried so far:
session.php
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
SessionTimeOut.php
Middleware
<?php
namespace App\Http\Middleware;
use Closure;
use App\Traits\CacheQueryResults;
class SessionTimeOut
{
use CacheQueryResults;
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// session()->forget('lastActivityTime');
if (! session()->has('lastActivityTime')) {
session(['lastActivityTime' => now()]);
}
// dd(
// session('lastActivityTime')->format('Y-M-jS h:i:s A'),
// now()->diffInMinutes(session('lastActivityTime')),
// now()->diffInMinutes(session('lastActivityTime')) >= config('session.lifetime')
// );
if (now()->diffInMinutes(session('lastActivityTime')) >= (config('session.lifetime') - 1) ) {
if (auth()->check() && auth()->id() > 1) {
$user = auth()->user();
auth()->logout();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
return redirect(route('users.login'));
}
}
session(['lastActivityTime' => now()]);
return $next($request);
}
}
Kernel.php
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SessionTimeOut::class,
],
];
Upvotes: 6
Views: 27718
Reputation: 1
Method 1 : Add Meta Tag to your app.blade.php file :
<meta http-equiv="refresh" content="{{ config('session.lifetime') * 60 }}; url=/logout">
Method 2 : with toaster
(function () {
const idleDurationSecs = 7200;
const warningDurationSecs = 5400;
let idleTimeout;
let warningTimeout;
const resetIdleTimeout = function () {
clearTimeout(warningTimeout);
warningTimeout = setTimeout(
() =>
toastr.warning(
"Please refresh the page to remain active",
"Your session is about to expire",
{ timeOut: 1800000 }
),
warningDurationSecs * 1000
);
clearTimeout(idleTimeout);
idleTimeout = setTimeout(
() => document.getElementById("logout-form").submit(),
idleDurationSecs * 1000
);
};
// Key events for reset time
resetIdleTimeout();
window.onmousemove = resetIdleTimeout;
window.onkeypress = resetIdleTimeout;
window.click = resetIdleTimeout;
window.onclick = resetIdleTimeout;
window.touchstart = resetIdleTimeout;
window.onfocus = resetIdleTimeout;
window.onchange = resetIdleTimeout;
window.onmouseover = resetIdleTimeout;
window.onmouseout = resetIdleTimeout;
window.onmousemove = resetIdleTimeout;
window.onmousedown = resetIdleTimeout;
window.onmouseup = resetIdleTimeout;
window.onkeypress = resetIdleTimeout;
window.onkeydown = resetIdleTimeout;
window.onkeyup = resetIdleTimeout;
window.onsubmit = resetIdleTimeout;
window.onreset = resetIdleTimeout;
window.onselect = resetIdleTimeout;
window.onscroll = resetIdleTimeout;
})();
Upvotes: 0
Reputation: 5731
You are comparing session lifetime same as in middleware.
That Means when session will expire, your middleware will not(never) called.And user will move to login page.
If you want to save entry in Database, You can set long-time session lifetime, and in middleware use your custom time to logout.
Change in config/session.php
'lifetime' => 525600, // for one year, it will be in minute, use as you want.
Change in middleware as below, log out after two hours.
if (now()->diffInMinutes(session('lastActivityTime')) >= (120) ) { // also you can this value in your config file and use here
if (auth()->check() && auth()->id() > 1) {
$user = auth()->user();
auth()->logout();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
return redirect(route('users.login'));
}
}
By this way your session will not expire automatically and you can manipulate data.
Upvotes: 8
Reputation: 564
please check less than 120 in middleware,ex 115 or 119 in below if condition and then check it
if (now()->diffInMinutes(session('lastActivityTime')) == config('session.lifetime')) {
....
}
Upvotes: 0
Reputation: 2945
Need to update the database before logout. Because after logout can't perform $user->update()
. so that try following way:
if (auth()->check() && auth()->id() > 1) {
$user = auth()->user();
$user->update(['is_logged_in' => false]);
$this->reCacheAllUsersData();
session()->forget('lastActivityTime');
//Add Logout method here..
auth()->logout();
return redirect(route('users.login'));
}
Upvotes: 0