Рубрики
Без рубрики

Весенняя сессия с MongoDB

Узнайте, как управлять весенними сессиями с помощью MongoDB.

Автор оригинала: baeldung.

1. Обзор

В этом кратком руководстве мы рассмотрим, как использовать весеннюю сессию с поддержкой MongoDB , как с загрузкой Spring, так и без нее.

Весенняя сессия также может быть поддержана другими магазинами, такими как Redis и JDBC .

2. Конфигурация пружинной Загрузки

Во-первых, давайте рассмотрим зависимости и конфигурацию, необходимые для загрузки Spring. Для начала давайте добавим в наш проект последние версии spring-session-data-mongodb и spring-boot-starter-data-mongodb :


    org.springframework.session
    spring-session-data-mongodb
    2.2.6.RELEASE


    org.springframework.boot
    spring-boot-starter-data-mongodb
    2.2.6.RELEASE

После этого, чтобы включить автоматическую настройку Spring Boot, нам нужно будет добавить тип хранилища Spring Session как mongodb в application.properties :

spring.session.store-type=mongodb

3. Конфигурация Пружины Без Пружинной Загрузки

Теперь давайте рассмотрим зависимости и конфигурацию, необходимые для хранения весеннего сеанса в MongoDB без загрузки Spring.

Аналогично конфигурации загрузки Spring, нам понадобится зависимость spring-session-data-mongodb . Однако здесь мы будем использовать зависимость spring-data-mongodb для доступа к нашей базе данных MongoDB:


    org.springframework.session
    spring-session-data-mongodb
    2.2.6.RELEASE


    org.springframework.data
    spring-data-mongodb
    2.2.6.RELEASE

Наконец, давайте посмотрим, как настроить приложение:

@EnableMongoHttpSession
public class HttpSessionConfig {

    @Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
        return new JdkMongoSessionConverter(Duration.ofMinutes(30));
    }
}

Аннотация @ Enable Mongo HttpSession включает конфигурацию, необходимую для хранения данных сеанса в MongoDB .

Кроме того, обратите внимание, что JdkMongoSessionConverter отвечает за сериализацию и десериализацию данных сеанса.

4. Пример применения

Давайте создадим приложение для тестирования конфигураций. Мы будем использовать Spring Boot, так как он быстрее и требует меньше настроек.

Мы начнем с создания контроллера для обработки запросов:

@RestController
public class SpringSessionMongoDBController {

    @GetMapping("/")
    public ResponseEntity count(HttpSession session) {

        Integer counter = (Integer) session.getAttribute("count");

        if (counter == null) {
            counter = 1;
        } else {
            counter++;
        }

        session.setAttribute("count", counter);

        return ResponseEntity.ok(counter);
    }
}

Как мы можем видеть в этом примере, мы увеличиваем счетчик при каждом попадании в конечную точку и сохраняем его значение в атрибуте сеанса с именем count .

5. Тестирование приложения

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

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

После этого мы запросим коллекцию MongoDB, чтобы получить данные сеанса, используя идентификатор сеанса:

@Test
public void 
  givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() {
    
    HttpEntity response = restTemplate
      .exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class);
    HttpHeaders headers = response.getHeaders();
    String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE);

    Assert.assertEquals(response.getBody(),
      repository.findById(getSessionId(set_cookie)).getAttribute("count").toString());
}

private String getSessionId(String cookie) {
    return new String(Base64.getDecoder().decode(cookie.split(";")[0].split("=")[1]));
}

6. Как Это Работает?

Давайте посмотрим, что происходит за кулисами весенней сессии.

SessionRepositoryFilter отвечает за большую часть работы:

  • преобразует HttpSession в MongoSession
  • проверяет, присутствует ли файл Cookie , и если да, загружает данные сеанса из хранилища
  • сохраняет обновленные данные сеанса в хранилище
  • проверяет действительность сеанса

Кроме того, SessionRepositoryFilter создает файл cookie с именем SESSION , который является HttpOnly и безопасным. Этот файл cookie содержит идентификатор сеанса, который является значением в кодировке Base64.

Чтобы настроить имя или свойства файла cookie, нам нужно будет создать компонент Spring типа Сериализатор файлов cookie по умолчанию.

Например, здесь мы отключаем свойство httponly файла cookie:

@Bean
public DefaultCookieSerializer customCookieSerializer(){
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        
    cookieSerializer.setUseHttpOnlyCookie(false);
        
    return cookieSerializer;
}

7. Сведения о сеансе, хранящиеся в MongoDB

Давайте запросим нашу коллекцию сеансов, используя следующую команду в нашей консоли MongoDB:

db.sessions.findOne()

В результате мы получим документ BSON, аналогичный:

{
    "_id" : "5d985be4-217c-472c-ae02-d6fca454662b",
    "created" : ISODate("2019-05-14T16:45:41.021Z"),
    "accessed" : ISODate("2019-05-14T17:18:59.118Z"),
    "interval" : "PT30M",
    "principal" : null,
    "expireAt" : ISODate("2019-05-14T17:48:59.118Z"),
    "attr" : BinData(0,"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAFY291bnRzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAC3g=")
}

_id – это UUID , который будет закодирован в Base64 с помощью файла cookie по умолчанию, сериализованного и отправленного в качестве значения в СЕАНСЕ файле cookie. Кроме того, обратите внимание, что атрибут attr содержит фактическое значение нашего счетчика.

8. Заключение

В этом уроке мы изучили весеннюю сессию, поддержанную MongoDB — мощным инструментом для управления HTTP-сессиями в распределенной системе. С учетом этой цели он может быть очень полезен при решении проблемы репликации сеансов в нескольких экземплярах приложения.

Как обычно, исходный код доступен на GitHub .