Session auto logout after inactivity
Ok, I'll throw my two cents into the ring here.
Even though it's in theory possible to implement this using rolling session
, I don't think you should...
- It would require each user action the send a request to the server, in order for the user not to be logged out.
- You miss an opportunity to inform your user that he/she will be logged out automatically soon (this is what the banks do, for example).
@Seth did point out in a comment above that there is actually a way to remedy this: "If the front end is separate from the server, you could have client side routing middleware that checks the cookie and visually logs you out, thus proving a good UX."
I think this is clever, but I also think it's like putting lipstick on a pig.
I believe that the best approach here is to handle this on the client side.
I would suggest something like this:
var AutoLogout = (function() {
function AutoLogout() {
this.events = ['load', 'mousemove', 'mousedown',
'click', 'scroll', 'keypress'];
this.warn = this.warn.bind(this);
this.logout = this.logout.bind(this);
this.resetTimeout = this.resetTimeout.bind(this);
var self = this;
this.events.forEach(function(event) {
window.addEventListener(event, self.resetTimeout);
});
this.setTimeout();
}
var _p = AutoLogout.prototype;
_p.clearTimeout = function() {
if(this.warnTimeout)
clearTimeout(this.warnTimeout);
if(this.logoutTimeout)
clearTimeout(this.logoutTimeout);
};
_p.setTimeout = function() {
this.warnTimeout = setTimeout(this.warn, 29 * 60 * 1000);
this.logoutTimeout = setTimeout(this.logout, 30 * 60 * 1000);
};
_p.resetTimeout = function() {
this.clearTimeout();
this.setTimeout();
};
_p.warn = function() {
alert('You will be logged out automatically in 1 minute.');
};
_p.logout = function() {
// Send a logout request to the API
console.log('Sending a logout request to the API...');
this.destroy(); // Cleanup
};
_p.destroy = function() {
this.clearTimeout();
var self = this;
this.forEach(function(event) {
window.removeEventListener(event, self.resetTimeout);
});
};
return AutoLogout;
})();
es2015
class AutoLogout {
constructor() {
this.events = ['load', 'mousemove', 'mousedown',
'click', 'scroll', 'keypress'];
this.warn = this.warn.bind(this);
this.logout = this.logout.bind(this);
this.resetTimeout = this.resetTimeout.bind(this);
this.events.forEach((event) => {
window.addEventListener(event, this.resetTimeout);
});
this.setTimeout();
}
clearTimeout() {
if(this.warnTimeout)
clearTimeout(this.warnTimeout);
if(this.logoutTimeout)
clearTimeout(this.logoutTimeout);
}
setTimeout() {
this.warnTimeout = setTimeout(this.warn, 29 * 60 * 1000);
this.logoutTimeout = setTimeout(this.logout, 30 * 60 * 1000);
}
resetTimeout() {
this.clearTimeout();
this.setTimeout();
}
warn() {
alert('You will be logged out automatically in 1 minute.');
}
logout() {
// Send a logout request to the API
console.log('Sending a logout request to the API...');
this.destroy(); // Cleanup
}
destroy() {
this.clearTimeout();
this.events.forEach((event) => {
window.removeEventListener(event, this.resetTimeout);
});
}
}
Partial polling solution:
var activityPolling = (function() {
var events = ['load', 'mousemove', 'mousedown', 'click', 'scroll', 'keypress'];
var active = true;
var timeout;
function poll() {
if(active) {
console.log('polling the server...')
}
}
function setIdle() {
active = false;
}
function setActive() {
active = true;
if(timeout)
clearTimeout(timeout);
timeout = setTimeout(setIdle, 30 * 60 * 1000);
}
function destroy() {
clearInterval(interval);
events.forEach(function(event) {
window.removeEventListener(event, setActive);
});
}
events.forEach(function(event) {
window.addEventListener(event, setActive);
});
setActive();
var interval = setInterval(poll, 60 * 1000);
return {
interval: interval,
destroy: destroy
}
})();
Rolling session may solve the purpose.
If you use the "rolling" option for session to "true," it will update the session timeout on new requests.
What you can do is: set max-age to 5 minutes.
maxAge: 30*10000
When there is no activity max-age will destroy the session. However, when there is any activity, rolling will renew the session to be alive for next 30 minutes.
Again, the word in-activity in this question is little misleading.
In-activity could be any (or all) of no-mouse-movement, no-mouse-click, or no-interaction-with-server.
If you refer inactivity as no-interaction-with-server, this logic will work. However for no-ui-interactions inactivity, you need to handle from client side