views:

949

answers:

5

How do I make sessions persist across browser/server restarts?
I'm using Google AppEngine.
I'm getting a new session id everytime I restart my browser and/or server.

String jSessionId=this.getThreadLocalRequest().getSession().getId();

End Goal
The big win I'm shooting for is long lived anonymous accounts.
For example, a user can do action A, have an anonymous account created on their behalf, then come back the next day and do action B with the same anonymous account they did action A with(assuming they didn't clear their cookies in between).

And at some point, once they've been drawn in, they can decide to validate/register their account and keep credit for the anonymous stuff they've already done.

A: 

Session persistent

SUMMARY: Here the Persistent mechanism means that you store the session data in the database, file storage or any other persistent storage. There are a few approaches for this mechanism, they are

  1. Using your application server's persistent mechanism for session data storage

  2. Using your own persistent mechanism by maintaining your own database schema

adatapost
A: 

Tomcat uses JSESSIONID cookie to keep track sessions across requests. However, it does this always,

cookie.setMaxAge(-1);

Which means it's a so-called session cookie and it doesn't survive browser restart.

The only way to get around this is to overwrite JSESSIONID in the response with an expiration time (keep everything else the same).

To persist sessions across Tomcat restart, you should use one of Persistent Managers. See Tomcat documentation for details,

http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html

Please notice that the session managers don't work well if you have multiple instances of the server behind a load balancer.

ZZ Coder
App Engine, not Tomcat.
Nick Johnson
App Engine was not mentioned when I answered the question so I assumed it was Tomcat.
ZZ Coder
App Engine does use a JSESSIONID cookie. I'll try to find out how to overwrite its expiration time.
antony.trupe
+1  A: 

Unless I'm mistaken here, and I well could be (if Google changes the internals of GAE), GAE uses both memcache and DataStore for session management. Hence, session data will be present in the DataStore during the course of the session.

If you intend to have persistent sessions, you have two possible course of action:

  1. Use cookies, not the existing JSESSIONID cookie, since you will not be able to modify it. However, I'm not so sure whether new cookies can be created at all, since support for the Cookie class does not seem to be mentioned. You might be in luck though, since GAE uses Jetty internally. The downside however, is that this data will be lost if the user clears his browser cookies.
  2. Design session management of your application well enough, such that session data can be persisted into the DataStore. That way, whenever such data changes, you can persist it into the DataStore, and pick up from the DataStore the next time the user authenticates into the application. This is assuming that the existing session management infrastructure provided by GAE is purging what it has stored in the DataStore (expected out of any application that performs session management - it should clean up invalid sessions).

PS: Server restarts on GAE should ideally be considered far and few. Of course, don't count on this, since GAE could have an outage, in which case the application itself would be unavailable.

Vineet Reynolds
I only need to figure out how to make the session id token persist. Its a pain in the butt during development, mainly. I already persist everything else to the DataStore. The consensus in this question(http://stackoverflow.com/questions/1382088/session-id-cookie-in-gwt-rpc) was to not make your own session id token.
antony.trupe
A: 

I ended up using java.util.UUID.randomUUID().toString() to generate my own unique session ID's.

antony.trupe
A: 

This is how i managed to do it:

req.getSession().setMaxInactiveInterval(TWO_WEEKS);
String sessionId = req.getSession().getId();
Cookie persistentSessionCookie = new Cookie("JSESSIONID", sessionId);
persistentSessionCookie.setPath("/");
persistentSessionCookie.setMaxAge(TWO_WEEKS);
resp.addCookie(persistentSessionCookie);

This way the session on GAE is stored for up to 2 weeks of inactivity. And the JSESSIONID on the client is persisted when browser is closed, for up to two weeks of inactivity as well.

This code needs to be called on every request (so abstract it nicely for re-use). It would have been nice if GAE allowed you to set these defaults, but oh well.

(Note that if you are debugging, when a browser sends cookies back to server in request, the max age is set to -1, but the browser itself stores the real expiry)

Patrick