MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Spring Session com MongoDB

1. Visão geral


Neste tutorial rápido, exploraremos como usar o Spring Session com o MongoDB, com e sem Spring Boot.

A Spring Session também pode ser apoiada com outras lojas, como Redis e JDBC.

2. Configuração do Spring Boot


Primeiro, vamos ver as dependências e a configuração necessária para o Spring Boot. Para começar, vamos adicionar as versões mais recentes de spring-session-data-mongodb e spring-boot-starter-data-mongodb ao nosso projeto:
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-mongodb</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

Depois disso, para habilitar a configuração automática do Spring Boot, precisaremos adicionar o tipo de armazenamento Spring Session como mongodb em application.properties :
spring.session.store-type=mongodb

3. Configuração do Spring sem Spring Boot


Agora, vamos dar uma olhada nas dependências e na configuração necessária para armazenar a sessão do Spring no MongoDB sem o Spring Boot.

Semelhante à configuração do Spring Boot, precisaremos do spring-session-data-mongodb dependência. No entanto, aqui usaremos o spring-data-mongodb dependência para acessar nosso banco de dados MongoDB:
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-mongodb</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

Por fim, vamos ver como configurar o aplicativo:
@EnableMongoHttpSession
public class HttpSessionConfig {

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

A @EnableMongoHttpSession anotação habilita a configuração necessária para armazenar os dados da sessão no MongoDB .

Além disso, observe que o JdkMongoSessionConverter é responsável por serializar e desserializar os dados da sessão.

4. Aplicativo de exemplo


Vamos criar um aplicativo para testar as configurações. Estaremos usando Spring Boot, pois é mais rápido e requer menos configuração.

Começaremos criando o controlador para lidar com as solicitações:
@RestController
public class SpringSessionMongoDBController {

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

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

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

        session.setAttribute("count", counter);

        return ResponseEntity.ok(counter);
    }
}

Como podemos ver neste exemplo, estamos incrementando counter em cada hit para o endpoint e armazenando seu valor em um atributo de sessão chamado count .

5. Testando o aplicativo


Vamos testar o aplicativo para ver se realmente conseguimos armazenar os dados da sessão no MongoDB.

Para fazer isso, acessaremos o endpoint e inspecionaremos o cookie que receberemos. Isso conterá um ID de sessão.

Depois disso, consultaremos a coleção do MongoDB para buscar os dados da sessão usando o ID da sessão:
@Test
public void 
  givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() {
    
    HttpEntity<String> 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. Como funciona?


Vamos dar uma olhada no que acontece na sessão de primavera nos bastidores.

O SessionRepositoryFilter é responsável pela maior parte do trabalho:
  • converte a HttpSession em uma MongoSession
  • verifica se há um Cookie presente e, em caso afirmativo, carrega os dados da sessão da loja
  • salva os dados atualizados da sessão na loja
  • verifica a validade da sessão

Além disso, o SessionRepositoryFilter cria um cookie com o nome SESSION que é HttpOnly e seguro. Este cookie contém o ID da sessão, que é um valor codificado em Base64.

Para personalizar o nome ou as propriedades do cookie, teremos que criar um bean Spring do tipo DefaultCookieSerializer.

Por exemplo, aqui estamos desabilitando o httponly propriedade do cookie:
@Bean
public DefaultCookieSerializer customCookieSerializer(){
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        
    cookieSerializer.setUseHttpOnlyCookie(false);
        
    return cookieSerializer;
}

7. Detalhes da sessão armazenados no MongoDB


Vamos consultar nossa coleção de sessões usando o seguinte comando em nosso console do MongoDB:
db.sessions.findOne()

Como resultado, obteremos um documento BSON semelhante a:
{
    "_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=")
}

O _id é um UUID que será codificado em Base64 pelo DefaultCookieSerializer e definido como um valor na SESSION biscoito. Além disso, observe que o attr O atributo contém o valor real do nosso contador.