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?
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).
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>
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With