Сессия Google App Engine теряет атрибут - PullRequest
0 голосов
/ 25 июня 2018

У меня есть приложение, которое хранит данные авторизации сеанса, которые работали в течение многих лет, теперь атрибут сеанса возвращает ноль. Я извлекаю данные сеанса в начале каждого запроса и устанавливаю их перед возвратом ответа. Приложение Spring 3 MVC, работающее по стандарту GAE.

Сеансы включены, <sessions-enabled>true</sessions-enabled>. Все мои объекты реализуют Сериализуемый. ОБНОВЛЕНИЕ - При проверке истории проекта я недавно обновился до Java 8. Я вернулся к Java 7, и сеанс все еще возвращает нулевой атрибут после установки. Вернитесь к Java 8.

protected void setSessionAccess(HttpServletRequest request, Access access) {
    logger.info("setting session access...");
    request.getSession().setAttribute(ACCESS, access);
}

protected Access getSessionAccess(HttpServletRequest request) {
    logger.info("getting session access...");
    Access access = (Access) request.getSession().getAttribute(ACCESS);
    if (access == null) {
        logger.log(Level.WARNING, "access is null, initializing access...");
        access = new Access();
    }
    return access;
}

При устранении неполадок я добавил <async-session-persistence enabled="true" /> и удалил его, поскольку данные сеанса также используются для целей навигации.

ОБНОВЛЕНИЕ - Пользователи сообщают, что могут поддерживать сеанс с некоторыми браузерами / платформами, а не с другими, что позволяет мне полагать, что это связано с файлами cookie. Я могу дублировать проблему, когда отключаю сеансовые куки. Перезапись URL-адреса решит эту проблему, но почему это неожиданно оборвалось?

Любая помощь очень ценится!

Ответы [ 2 ]

0 голосов
/ 23 июля 2019

Может быть не связано, так как я разрабатываю в Python / Flask, но я терял свои сеансы, так как неправильно установил «секретный ключ» приложения на что-то случайное, генерируемое в каждом экземпляре.Это означало, что пользователь был перенесен из экземпляра в экземпляр, к которому сеанс не был доступен, поскольку каждый экземпляр имел свой ключ, с которым он подписывал файлы cookie / сеансы.

0 голосов
/ 14 июля 2018

Я отправил запрос с помощью трекера общедоступных вопросов , как подсказывает Ггримальдо .

Они подтвердили, что, скорее всего, это проблема, связанная с браузером, поскольку сеансы не теряются с некоторыми браузерами и платформами. Они предложили установить cookie с идентификатором сеанса и прочитать идентификатор сеанса, если данные сеанса были нулевыми. Я нашел этот пост , описывающий, как читать данные _ah_session из хранилища данных, и реализовал его таким образом,

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);
}

позвонил отсюда,

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);
}

Я попрошу своих пользователей повторить попытку и немного посмотреть журналы. Это было особенно раздражающим вопросом, но, поскольку я поддерживаю этот сайт в качестве волонтера клуба, никаких жалоб от тех, кто хочет заняться техническим обслуживанием, нет. Я выложу обновление. Если jsessionid изменчив, мне придется прибегнуть к созданию собственного cookie-файла (argh).

Итак, вот мой код установки cookie, скопированный из другого места в 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);
}

Я устанавливаю это при первом установлении сеанса и обновляю его каждый раз, когда сеанс сохраняется. Существует некоторая дополнительная условная логика для установки или обновления значения сеанса в файле cookie при каждом сохранении атрибута сеанса в сеансе. Это работает, и мои пользователи счастливы.

Нет очевидной причины, почему это произошло в первую очередь, так что, надеюсь, никто не столкнется с этим. Если хотите, проголосуйте или оставьте комментарий, чтобы я понял, если это только я, спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...