Reputation: 2397
Our application logs off after 30 min and gets redirected to login page,i am specifying session timeout in web.xml and using a requestProcessor for redirecting.I want to show to the user a message saying your session got expired once the session expires,how can i do that.Auto log off ? I would like to prompt the error message on the page"The session is timeout, please login again" . Then how could I detect the session is timeout? will any methods trigger automatically?
Upvotes: 5
Views: 15960
Reputation: 3523
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">
Upvotes: 1
Reputation: 1108642
Create an activity checker which checks every minute if any user activity has taken place (mouseclick, keypress) and performs a heartbeat to the server side to keep the session alive when the user is active and does nothing when the user is not active. When there is no activity for 30 minutes (or whatever default session timeout is been set on server side), then perform a redirect.
Here's a kickoff example with little help of jQuery to bind click and keypress events and fire ajax request.
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$.active = false;
$('body').bind('click keypress', function() { $.active = true; });
checkActivity(1800000, 60000, 0); // timeout = 30 minutes, interval = 1 minute.
});
function checkActivity(timeout, interval, elapsed) {
if ($.active) {
elapsed = 0;
$.active = false;
$.get('heartbeat');
}
if (elapsed < timeout) {
elapsed += interval;
setTimeout(function() {
checkActivity(timeout, interval, elapsed);
}, interval);
} else {
window.location = 'http://example.com/expired'; // Redirect to "session expired" page.
}
}
</script>
Create a Servlet
which listens on /heartbeat
and does basically just the following:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
request.getSession();
}
to keep the session alive.
When you store the logged-in user in the session, it will be "automagically" logged out whenever the session expires. So you don't need to manually logout the user.
Upvotes: 11
Reputation: 282
Include a javascript utility function inside your JSP and ping the server every 31 minutes. The above mentioned utility function should be using setTimeout() JS function internally.
setTimeout ( "checkServerSession()", /* intervalInMilliSeconds */ 31000);
Note that
checkServerSession()
is a regular JS function which may fire HTTP requests. If the request is successful session exists otherwise show the prompt to the user.
Upvotes: 0
Reputation: 31371
Create a Listener class implementing HttpSessionListener
and define it in web.xml
This will notify you when any session is destroyed. Use the sessionDestroyed()
method.
See a full example here:
http://www.mkyong.com/servlet/a-simple-httpsessionlistener-example-active-sessions-counter/
Upvotes: 2
Reputation: 11502
If you're using servlet sessions, you can check to see if the session the jsp / servlet is returning is new using the isNew() method. If yes, then the user's session has expired and you can display the relevant messages.
Upvotes: 0