Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-idle issue if multiple tabs/windows are opened in browser

I have a requirement where I have to logout user if it is idle for some time. I am using ng-idle 0.3.2.

I am getting issue if there are more than one tabs/windows opened in browser. If I am working on a tab and the tabs which are not active getting logged-out while the active tab I am working on is still logged-in because that is active.

How to prevent logout from inactive tabs while I am working on another similar tab?

like image 627
A_J Avatar asked May 01 '14 19:05

A_J


2 Answers

Summary

Use localStorage to store a timestamp for the last known activity event in any tab running your app. Poll that value every few seconds in every instance of your app that is running. If it has been updated, reset the ng-idle timer to avoid premature logout (or whatever action you have set to occur when the $idleTimeout event is broadcast).

How To

Create a directive to embody the behavior described above:

.directive('idle', function($idle, $timeout, $interval){
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      var timeout;
      var timestamp = localStorage.lastEventTime;

      // Watch for the events set in ng-idle's options
      // If any of them fire (considering 500ms debounce), update localStorage.lastEventTime with a current timestamp
      elem.on($idle._options().events, function(){
        if (timeout) { $timeout.cancel(timeout); }
        timeout = $timeout(function(){
          localStorage.setItem('lastEventTime', new Date().getTime());
        }, 500);
      });

      // Every 5s, poll localStorage.lastEventTime to see if its value is greater than the timestamp set for the last known event
      // If it is, reset the ng-idle timer and update the last known event timestamp to the value found in localStorage
      $interval(function() {
        if (localStorage.lastEventTime > timestamp) {
          $idle.watch();
          timestamp = localStorage.lastEventTime;
        } 
      }, 5000);
    }
  }
})

Add the directive attribute to the body tag to ensure that all mouse and keyboard events within the page are detected:

<body ng-app="myApp" idle>

Demo

Open up and run this Plunk in multiple tabs along with a console for each. Move your mouse cursor over the body content and watch the events logged to both consoles.

like image 176
Marc Kline Avatar answered Nov 10 '22 01:11

Marc Kline


I haven't worked with ngIdle yet but typically you need to communicate with server in these situations. i.e. In $keepalive event, send a request to server to store the last activity time in session. In the $idleWarn, send a request to server to get the latest activity time stamp, if user is active in other tabs then you would get a recent timestamp, hence you can stop the timeout process and send a keepalive.

like image 27
Aidin Avatar answered Nov 09 '22 23:11

Aidin