MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Sessione primaverile con MongoDB

1. Panoramica

In questo breve tutorial, esploreremo come utilizzare la sessione di primavera supportata da MongoDB, sia con che senza Spring Boot.

Spring Session può anche essere supportato da altri negozi come Redis e JDBC.

2. Configurazione Spring Boot

Per prima cosa, esaminiamo le dipendenze e la configurazione richiesta per Spring Boot. Per cominciare, aggiungiamo le ultime versioni di spring-session-data-mongodb e spring-boot-starter-data-mongodb al nostro progetto:

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

Dopodiché, per abilitare la configurazione automatica di Spring Boot, dovremo aggiungere il tipo di archivio Spring Session come mongodb in application.properties :

spring.session.store-type=mongodb

3. Configurazione a molla senza avvio a molla

Ora, diamo un'occhiata alle dipendenze e alla configurazione richiesta per archiviare la sessione Spring in MongoDB senza Spring Boot.

Simile alla configurazione Spring Boot, avremo bisogno di spring-session-data-mongodb dipendenza. Tuttavia, qui utilizzeremo spring-data-mongodb dipendenza per accedere al nostro database 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>

Infine, vediamo come configurare l'applicazione:

@EnableMongoHttpSession
public class HttpSessionConfig {

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

La @EnableMongoHttpSession l'annotazione abilita la configurazione richiesta per memorizzare i dati della sessione in MongoDB .

Inoltre, nota che il JdkMongoSessionConverter è responsabile della serializzazione e deserializzazione dei dati della sessione.

4. Esempio di applicazione

Creiamo un'applicazione per testare le configurazioni. Useremo Spring Boot, poiché è più veloce e richiede meno configurazione.

Inizieremo creando il controller per gestire le richieste:

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

Come possiamo vedere in questo esempio, stiamo incrementando contatore su ogni hit all'endpoint e memorizzandone il valore in un attributo di sessione denominato count .

5. Testare l'applicazione

Testiamo l'applicazione per vedere se siamo effettivamente in grado di archiviare i dati della sessione in MongoDB.

Per fare ciò, accederemo all'endpoint e ispezioneremo il cookie che riceveremo. Questo conterrà un ID sessione.

Successivamente, interrogheremo la raccolta MongoDB per recuperare i dati della sessione utilizzando l'ID sessione:

@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. Come funziona?

Diamo un'occhiata a cosa succede dietro le quinte della sessione primaverile.

Il Filtro SessionRepository è responsabile della maggior parte del lavoro:

  • converte la HttpSession in una MongoSession
  • verifica se è presente un Cookie presente e, in tal caso, carica i dati della sessione dall'archivio
  • salva i dati della sessione aggiornati nello store
  • verifica la validità della sessione

Inoltre, il SessionRepositoryFilter crea un cookie con il nome SESSIONE questo è solo HTTP e sicuro. Questo cookie contiene l'id di sessione, che è un valore con codifica Base64.

Per personalizzare il nome o le proprietà del cookie, dovremo creare un bean Spring di tipo DefaultCookieSerializer.

Ad esempio, qui stiamo disabilitando httponly proprietà del cookie:

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

7. Dettagli della sessione archiviati in MongoDB

Interroghiamo la nostra raccolta di sessioni utilizzando il seguente comando nella nostra console MongoDB:

db.sessions.findOne()

Di conseguenza, otterremo un documento BSON simile 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=")
}

Il _id è un UUID che sarà codificato in Base64 da DefaultCookieSerializer e impostare come valore nella SESSIONE biscotto. Inoltre, nota che il attr contiene il valore effettivo del nostro contatore.