3

Recently came across this problem. The scenario is, let's say I have two tabs open (A and B), I login with Tab A authenticates redirects to the home page. Then selected a link instead of just entering, I right click and pick "Open link in a new tab" thus having Tab B. At this point I start navigating for 30 mins a alert pop up saying my "Session has been finish. Please login again.". Instead of being redirected to the Login page I was redirected to the home page. (The alert must be coming for Tab A)

If I was dealing with only one Tab this isn't an Issue after the alert I would go directly to the Login Page.

I have two set of codes one handles the actual session expiration and the other gives out the alert.

This code is for the alert:

function idleLogout() {
var t;
window.onload = resetTimer;
window.onmousemove = resetTimer;
window.onmousedown = resetTimer; 
window.onclick = resetTimer;     
window.onscroll = resetTimer;   
window.onkeypress = resetTimer;

function logout() {
    alert("Session has been finish. Please login again.");
    window.location.href = '{{url("")}}';
}

function resetTimer() {
    clearTimeout(t);
    t = setTimeout(logout, {{ env('SESSION_LIFETIME')*60*1000 }} );  
}
}
idleLogout();

Code is working as intended but it can be implemented better.

Btw, if it matters using PHP Laravel 5

1 Answers1

1

The problem is that you're using JavaScript to handle your timeouts. JavaScript (by default) is only confined to a single tab. While you could make use of COOKIES in JavaScript to communicate between tabs, it would make far more sense to handle session timeouts through server-side SESSION variables, which persist across tabs.

A thirty minute forced timeout can be achieved in PHP, courtesy of this answer:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

Hope this helps.

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • The problem you will have with this is just calling session start will re-new the session time, unless you track time separately which is what this does. but that becomes cumbersome. A first step to this is storing the session in the DB, then you can access the DB outside of the session and use the session time itself, by only passing a user id back via ajax. But it's not trivial to do that. – ArtisticPhoenix Jan 26 '18 at 02:42