My requirement is to notify the user with a popup saying that the user session is about to time out in x seconds in case user does not perform any activity on the web page.<
Either it may be simple servlet, spring-mvc or spring-security auto logout is not possible without perfect client side logic.
Considering application will have both type of request
Auto logout needs very calculated logic. Presenting my autologout functionality implementation with following
1. Include auto logout script in required JSP pages as given below.
....
</body>
<jsp:include page="../template/autologout-script.jsp"></jsp:include>
</html>
2. Create a JSP page, autologout-script.jsp and add below code. Note: No editing/configuring is required
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script>
$(document).ready(function()
{
var timeOutTimeInSeconds = ${ timeOutTimeInSeconds };
var showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
var sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
var timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
var badgeTimerId;
window.localStorage.setItem("AjaxRequestFired", new Date());
function redirectToLoginPage(){
//location.href = '<c:url value="/" />'+'${loginPageUrl}';
window.location.reload();
}
$(document).ajaxComplete(function () {
resetTimer();
});
$(window).bind('storage', function (e) {
if(e.originalEvent.key == "AjaxRequestFired"){
console.log("Request sent from another tab, hence resetting timer")
resetTimer();
}
});
function resetTimer()
{
showTimerTimeInSeconds= ${ showTimerTimeInSeconds };
console.log("timeOutTimeInSeconds : "+timeOutTimeInSeconds)
window.localStorage.setItem("AjaxRequestFired", new Date());
window.clearInterval(sessionCheckIntervalId);
sessionCheckIntervalId = setInterval(redirectToLoginPage, timeOutTimeInSeconds * 1000);
window.clearInterval(timerDisplayIntervalId);
timerDisplayIntervalId = setInterval(showTimer, (timeOutTimeInSeconds - showTimerTimeInSeconds) * 1000);
hideTimer();
}
function showTimer()
{
$('#sessionTimeRemaining').show();
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
window.clearInterval(timerDisplayIntervalId);
badgeTimerId = setInterval(function(){
$('#sessionTimeRemainingBadge').html(showTimerTimeInSeconds--);
}, 1000);
}
function hideTimer()
{
window.clearInterval(badgeTimerId);
$('#sessionTimeRemaining').hide();
}
});
</script>
3. Configure session attributes to configuring timeout setting Note: Configure this after session creation. You can implement HttpSessionListener sessionCreated method and set the following configuration as per your requirement.
session.setMaxInactiveInterval(300);
session.setAttribute("timeOutTimeInSeconds", 300);
session.setAttribute("showTimerTimeInSeconds", 30);
4. Add below html for displaying timer.
Note: it can be moved to autologout-script template page if you are good at CSS. Hence you can avoid to add this in each and every page.
Include bootstrap or add your custom css.
<span class="badge badge-primary" title="click to keep session alive" id="sessionTimeRemaining"
onclick="ajaxSessionRefresh()" style="display:none;">
<i class="badge badge-danger" id="sessionTimeRemainingBadge" style="float:left">30</i>
<small>Refresh</small>
<i class="glyphicon glyphicon-refresh"></i>
</span>
That is all about a simple auto logout implementation.
You can download working example from my github repository
Autologout using simple servlet example
Autologout using spring-security java configuration example
Autologout using spring-security xml configuration example
Limitations/Improvements required
1. If maximum allowed session is one, if session is taken from another system, AJAX request will fail. It needs to be handled to redirect to login page.
2. Use ajaxStart() instead of ajaxComplete() to have exact sync of idleTime values between server and browser.
Requirements
1. Jquery
response.setHeader("Refresh", "60; URL=login.jsp");
<meta http-equiv="refresh" content="60; url=login.jsp">
Make use of HttpSession#getMaxInactiveInterval() and setTimeout(). There's no need for Ajax in this particular purpose, unless you want to postpone the timeout on every client activity (polling).
Basic example:
<script>
var secondsBeforeExpire = ${pageContext.session.maxInactiveInterval};
var timeToDecide = 15; // Give client 15 seconds to choose.
setTimeout(function() {
alert('Your session is about to timeout in ' + timeToDecide + ' seconds!')
}, (secondsBeforeExpire - timeToDecide) * 1000);
</script>
To decrement the time inside the message magically, then instead of the basic alert()
you'll need an overlay with a div wherein you have control over the content through HTML DOM tree and make use of another setTimeout()
on 1 second to change the text dynamically.
Note that this script has to be served by the JspServlet
to get the EL to work. Thus, you need to put the script in the HTML <head>
of the JSP page, or if you really want to have all the JS in a separate *.js
file, then you need to let the JspServlet
handle any *.js
requests as well.
I don't think that Java/Java EE will be really helpful here as this need to be handled on the client-side (i.e. using JavaScript). One solution I can think of would be to set a kind of timer that would notify the user a few minutes before the server's timeout.
While googling about this, I found Eric Pascarello's Update User's Session with AJAX blog post (and the reloaded version Updating User Session with Ajax - Round 2) that precisely describes such a solution (and use an XMLHttpRequest
to update the session). His Ajax Session Management script is available here.