In the web app (Servlet-JSP MVC) I am working on I have set session timeout as -1, which means the session will never expire until it is intentionally invalidated during logout.
<session-config>
<session-timeout>-1</session-timeout>
</session-config>
But if the user stays idle (i.e no activity on application) and then refreshes the application after some time, the session expires.
I am using Apache Tomcat 7.0 with XAMPP for my application.
What might be the reason? What can be done to keep the session alive indefinitely? What does "-1" in session-timeout tag actually means?
Better approach is use a ajax call to refresh the session, but not set the session-timeout too long, because the user can close browser without quitting, then session entities will keep in memory but never will be used again.
You settings not work may caused by conflict of settings in such three places:
(1) Java Code
session.setMaxInactiveInterval(600);
(2) webapp's web.xml
(3) Contianer's(tomcat?)settings conf/web.xml or Catalina/localhost/yourapp/context.xml or server.xml or event in your app's submodule jars.
<Context path="/" docBase="/yourapp/base"
defaultSessionTimeOut="3600" ... />
The priorities (1)>(2)>(3)
————EDIT————
According the tomcat 7 documentation, in case you use SSL (https://tomcat.apache.org/tomcat-7.0-doc/config/http.html)
sessionTimeout
The time, in seconds, after the creation of an SSL session that it will >timeout. Use 0 to specify an unlimited timeout. If not specified, a >default of 86400 (24 hours) is used.
Use 0 to specify an unlimited timeout
And this link JSESSIONID Cookie with Expiration Date in Tomcat and this https://stackoverflow.com/a/13463566/1484621 worth a look
The correct way to test session is request.getSession(false) == null, or request.getSession(true).isNew().
According to the source code
/**
* Set the default session timeout (in minutes) for this
* web application.
*
* #param timeout The new default session timeout
*/
#Override
public void setSessionTimeout(int timeout) {
int oldSessionTimeout = this.sessionTimeout;
/*
* SRV.13.4 ("Deployment Descriptor"):
* If the timeout is 0 or less, the container ensures the default
* behaviour of sessions is never to time out.
*/
this.sessionTimeout = (timeout == 0) ? -1 : timeout;
support.firePropertyChange("sessionTimeout",
oldSessionTimeout,
this.sessionTimeout);
}
the session-timeout set to 0 or -1 will have same result
Related
In my Vaadin application I have an issue when Vaadin does not invalidate session after "Session timeout" message. After getting this message users sometimes are able to click the link or refresh the page and continue working as if they are still being logged in.
I use the following parameters:
closeIdleSessions=true
heartbeatInterval=60
session-timeout=15
Last parameter (session-timeout) is also set in context.xml (session-timeout=900) and web.xml (session-config/session-timeout=15) as I didn't get clear from vaadin documentation, is there such a parameter for vaadin servlet or not.
Did anybody face the titular problem?
UPDATE 1: Fixed parameters snippet.
UPDATE 2: SessionDestroyListener.sessionDestroy does not get triggered when Session expired message appears.
UPDATE 3: Previous error appeared because of code mistake. Now SessionDestroyListener.sessionDestroy gets called, but I have no access to HttpSession from given event.
Here is my SessionDestroyListener code (please note the comment in one of if branches):
private static class SynchronizerSessionDestroyListener implements SessionDestroyListener {
#Override
public void sessionDestroy(SessionDestroyEvent event) {
if (event.getSession() != null){
WrappedSession wrappedSession = event.getSession().getSession();
if (wrappedSession instanceof WrappedHttpSession){
WrappedHttpSession wrappedHttpSession = (WrappedHttpSession) wrappedSession;
HttpSession httpSession = wrappedHttpSession.getHttpSession();
if (httpSession != null){
try {
httpSession.invalidate();
logger.debug("Session '{}' was invalidated", httpSession.getId());
} catch (IllegalStateException e){
// do nothing, already invalidated
logger.debug("Session '{}' was already invalidated: {}", httpSession.getId(), e.getMessage());
}
} else {
logger.warn("Could not invalidate http session for vaadin session: http session is null"); // THIS IS THE BRANCH WHICH IS ACTUALLY GET EXECUTED ON 'SESSION EXPIRED' MESSAGE: event.getSession().getSession() is null!
}
} else {
logger.warn("Could not invalidate http session for vaadin session: event session is not an http session");
}
} else {
logger.warn("Could not invalidate http session for vaadin session: event session is null");
}
}
}
Here is how I attach the listener:
public class X extends VaadinServlet {
// different class members
#Override
protected void servletInitialized() throws ServletException {
super.servletInitialized();
getService().addSessionDestroyListener(new SynchronizerSessionDestroyListener());
}
}
I will try to explain how the session invalidation basically works, maybe this helps (I can't read too much information out of your question):
Usually the session will timeout after the specified time inside the
session-timeout parameter.
BUT you have the take the heartbeat
interval into account. If your heartbeat interval is shorter
than the session timeout (it usually is), the heartbeat will keep the session alive
forever.
Thats where the parameter closeIdleSessions is relevant. Setting
this parameter to true the browser will not take the heartbeats as
a valid request for the timeout, but the last, non-heartbeat
request.
Second BUT: When will the timeout be recognized? The client-side engine can only recognize this at a heartbeat or if the user takes some action (as in both cases a request to the server is done). By consequence the actual timeout will not occur when the specified timeout has passed, but at the next heartbeat after the timeout.
Other situation: after 3 missing heartbeats, the server also closes the session. E.g. if the browser is closed this will cause the session to be invalidated as no heartbeats are sent.
Sample web.xml to explain better:
<context-param>
<!-- ATTENTION: This value is set in SECONDS -->
<param-name>heartbeatInterval</param-name>
<param-value>180</param-value>
</context-param>
<session-config>
<!-- ATTENTION: This value is set in MINUTES -->
<session-timeout>4</session-timeout>
</session-config>
<servlet>
<servlet-name>VaadinServlet</servlet-name>
<servlet-class>com.example.VaadinServlet</servlet-class>
<init-param>
<param-name>closeIdleSessions</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
Using the above web.xml the session will timeout after 6 minutes (without user interaction).
Explanation:
the session timeout is set to 4 minutes, but there is no heartbeat at 4 minutes. The next heartbeat will be at 6 minutes. Now the client side engine knows that the session actually timed out and will show the according message.
I am not sure if this is the same process when using Vaadin Push as there we have a continous channel from client to server.
Sources:
Book of Vaadin - 4.8.7. Session Expiration
Book of Vaadin - 4.9.6. Other Servlet Configuration Parameters, Session Timeout After User Inactivity
Additional information:
Upcoming Vaadin 7.6 seems to improve client-server connection stability: Blog Post
Is it possible to manually reset the timeout interval of a specific session for a user that is currently logged in my web app?
I would like the ability to do something similar to this :
public void keepAliveForUser(long userID) {
Session session = this.userSessionManager.getUserSessionById(userID);
session.resetTimeOut();
}
P.S - keep in mind this function is not being called in a follow up to a user request. (i.e. It's called from a cron job, a scheduled task, etc...)
Thanks!
You can use HttpSession#setMaxInactiveInterval to change the session expiry time on the fly
Java Doc
Specifies the time, in seconds, between client requests before the
servlet container will invalidate this session. A negative time
indicates the session should never timeout.
Usage
//session will expire after 2 hours of inactivity
session.setMaxInactiveInterval(2 * 60 * 60);
Session timeout hierarchy:
$tomcat_home/conf/web.xml
$your_webapp/WEB-INF/web.xml
manual invocation of HttpSession.setMaxInactiveInterval(int)
I have a requirement to set the session timeout of 40 seconds. I know we keep normally to 20 minutes.
But my current application requirement is to keep the session timeout to 40 seconds. The web.xml is taking only integer value as 1 but it is not taking 0.6. Is there any way to write this? We are running our java web application on Apache tomcat server.
So how do I set session timeout in seconds in web.xml?
Using the deployment descriptor, you can only set the timeout in minutes:
<session-config>
<session-timeout>1</session-timeout>
</session-config>
But using the HttpSession API you can set the session timeout in seconds for a servlet container:
HttpSession session = request.getSession();
session.setMaxInactiveInterval(40);
Suggested reading: Deployment Descriptor Elements
well in web.xml file you can provide in minutes
<session-config>
<session-timeout>Minutes</session-timeout>
</session-config>
but you programatically provide values in seconds
HttpSession session = request.getSession();
session.setMaxInactiveInterval(20*60);
1) Timeout in the deployment descriptor (web.xml)
– Specified the timeout value in “minute” , enclose with “session-config” element.
Markup
<web-app ...>
<session-config>
<session-timeout>20</session-timeout>
</session-config>
</web-app>
The above setting is apply for the entire web application, and session will be kill by container if client doesn’t make any request after 20 minutes.
2) Timeout with setMaxInactiveInterval()
– You can manually specified the timeout value in “second” for a particular session.
Java
HttpSession session = request.getSession();
session.setMaxInactiveInterval(20*60);
The above setting is only apply on session which call the “setMaxInactiveInterval()” method, and session will be kill by container if client doesn’t make any request after 20 minutes.
you can override the session timeout through "setMaxInactiveInterval()".
HttpSession session = request.getSession();
session.setMaxInactiveInterval(20000);
here it will take the time in milliseconds, means in next 20 seconds session will get expire.
How do i set session timeout in seconds in web.xml?
Solution: Try this
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET) // Your token here
res.cookie('Cookie', token, { expire: new Date(Date.now()+ 9999)})
what is java app engine,default session time out ?
will that be any bad impact if we set sesion time out to very very long time, since google app engine session is just store in datastore by default? (just like facebook, each time you go to the page, the session still exist forever) ?
Default session timeout is set to 30 Minutes. (you can verify it calling getMaxInactiveInterval method)
With that fairly limited info about your app, I don't see any impact.
Using setMaxInactiveInterval(-1) indicates that the Session should never timeout.
Keep in mind that you also need to overwrite the JSESSIONID cookie MaxAge to prevent to lose the Session when the browser is closed.
I've just tested on my GAE webapp and the default timeout is getMaxInactiveInterval()=86400 (s) = 24 hours = 1 day
I have a jsp servlet based application, with session time out of 30 mins, I want to invalidate the session as soon as a person closes the browser window intentionally or accidentally (OS shutdown/close from tast manager/powerdown)
Can I put a check for that and invalidate the session?
It is not possible to handle this scenario .
There are some browsers which provide this setting as their preference , but you can't handle this programitically.
At max:
You can make a poll from page(may be header) same as gtalk in gmail as soon as connection closes wipe that session out.
Why do you want to do that, you have already configured that in server that ,session should stay idle for 30 mins,after that it will expire in server.
if you want to do that use the following javascript or jquery(better for cross browser) , when the browse close event happens send an ajax request to invalidate session by running following code in jsp
(request.getSession(false).setMaxInactiveInteral(0);)
From javascript
<body onbeforeunload="doAjaxCall();">
(or)
jQuery(window).bind("beforeunload", function(){
// Do ajax request and dont wait for the response.
});
You can implement the server push ajax polling , for example think that session is going to expire in another 2 seconds , send a server side request to client to invalidate the cookie and also in the server you can invalidate the session.
if ( (getcurrentTime() - session.getCreationTime()) > 2000 ) {
}
While the page is rendered , get the maxinactiveinterval and then set the value to the JavaScript variable , then use setInterval function , pass the inactiveinterval value to function , once the timeout happens you can set the cookie to expire.
No I don't believe you can do that as there are no hooks available in the browser to get it to send a disconnect notification (of some sort) when it closes and I don't think there is a server-side mechanism to interrogate recent sessions to test their connection status.
If you are using tomcat 5.0/5.5/6.0 container, the cookie generated by tomcat session manager to track the session (JSESSIONID) is a per-session cookie (browser memory only cookie) instead of a persistent cookie (write to disk). That's because the session manager does (hardcoded) setMaxAge(-1), so that the generated HTTP-response contains:
Set-Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/ and no Expire=date.
So when the browser is closed (all browser windows, or just the window containing the cookie, depending on the variuos browser implementations), the cookie - and the session - are lost. [*]
This has nothing to do with <session-timeout>, which is a setting that tells the tomcat server-side session manager to expire sessions when idle for more time than specified.
[*] they will still be persisted on disk on the server-side, till session-timeout expires, but there wont be a request with a cookie activating them.