I have an application that stores session authorization details that has been working for years, now the session attribute is returning null. I retrieve the session data at
Could be unrelated as I'm developing in Python/Flask, but I was losing my sessions as I had incorrectly set the application "secret key" to something randomly generated on each instance. This meant as the user was transferred from instance to instance the session was unable to be accessed as each instance had a different key it was signing cookies/sessions with.
I submitted a request with the public issue tracker as Ggrimaldo suggests.
They confirmed it's most likely a browser related issue, since sessions aren't lost with some browsers and platforms. They suggested setting a cookie with the session id, and reading the session id if the session data was null. I found this post describing how to read the _ah_session data from the datastore, and implemented it this way,
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key sessionKey = KeyFactory.createKey("_ah_SESSION", "_ahs" + sessionId);
Entity sessionEntity = datastore.get(sessionKey);
Blob blob = (Blob) sessionEntity.getProperty(_VALUES);
byte[] sessionBytes = blob.getBytes();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(sessionBytes);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (Map<String, Object>) objectInputStream.readObject();
} catch (EntityNotFoundException e) {
logger.log(Level.INFO, e.getMessage());
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
called from here,
String mySessionId = null;
for (Cookie cookie : cookies) {
if ("MYSESSIONID".equals(cookie.getName())) {
mySessionId = cookie.getValue();
}
}
// returning code is above
sessionMap = gcpSessionService.getGcpSession(swgcSessionId);
if (sessionMap != null) {
access = (Access) sessionMap.get(ACCESS);
}
I'll ask my users to retry and watch the logs a bit. This has been a particularly annoying issue, but since I maintain this site as a volunteer for a club, no complaints from anyone wanting to take up maintenance. I'll post an update. If the jsessionid is volatile, I'll have to resort to creating my own cookie (argh).
So, argh, here's my cookie setting code, copied from elsewhere on stackoverflow,
protected void setMySessionCookie(HttpServletResponse response, String jSessionId) {
logger.log(Level.INFO, "setting MYSESSIONID = " + jSessionId);
final String cookieName = "MYSESSIONID";
// you could assign it some encoded value
final String cookieValue = jSessionId;
// TODO enforce SSL
final Boolean useSecureCookie = false;
final int expiryTime = -1; // 24h in seconds
final String cookiePath = "/";
Cookie cookie = new Cookie(cookieName, cookieValue);
// determines whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL
cookie.setSecure(useSecureCookie);
// A negative value means that the cookie is not stored persistently and will be deleted when the Web browser exits. A zero value causes the cookie to be deleted.
cookie.setMaxAge(expiryTime);
// The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories
cookie.setPath(cookiePath);
response.addCookie(cookie);
}
I set this when the session is first established, and update it each time the session is saved. There's some additional conditional logic for setting or updating the session value in the cookie each time the session attribute is saved in the session. It's working and my users are happy.
There's no obvious reason why this occurred in the first place, so hopefully no one will run into it. I you do, vote up or leave a comment so I get an idea if it's just me, thanks!