Google App Engine session loses attribute

前端 未结 2 1952
清歌不尽
清歌不尽 2021-01-16 07:49

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

2条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-16 08:05

    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) 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!

提交回复
热议问题