1. Présentation
Dans ce rapide didacticiel, nous allons explorer comment utiliser la session Spring soutenue par MongoDB, avec et sans Spring Boot.
Spring Session peut également être soutenu par d'autres magasins tels que Redis et JDBC.
2. Configuration du démarrage du printemps
Examinons d'abord les dépendances et la configuration requise pour Spring Boot. Pour commencer, ajoutons les dernières versions de spring-session-data-mongodb et spring-boot-starter-data-mongodb à notre projet :
<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>
Après cela, pour activer la configuration automatique de Spring Boot, nous devrons ajouter le type de magasin Spring Session en tant que mongodb dans application.properties :
spring.session.store-type=mongodb
3. Configuration Spring sans Spring Boot
Voyons maintenant les dépendances et la configuration requise pour stocker la session Spring dans MongoDB sans Spring Boot.
Semblable à la configuration de Spring Boot, nous aurons besoin de spring-session-data-mongodb dépendance. Cependant, ici, nous utiliserons le spring-data-mongodb dépendance pour accéder à notre base de données 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>
Voyons enfin comment configurer l'application :
@EnableMongoHttpSession
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter(Duration.ofMinutes(30));
}
}
La @EnableMongoHttpSession l'annotation active la configuration requise pour stocker les données de session dans MongoDB .
Notez également que le JdkMongoSessionConverter est responsable de la sérialisation et de la désérialisation des données de session.
4. Exemple d'application
Créons une application pour tester les configurations. Nous utiliserons Spring Boot, car il est plus rapide et nécessite moins de configuration.
Nous allons commencer par créer le contrôleur pour gérer les requêtes :
@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);
}
}
Comme nous pouvons le voir dans cet exemple, nous incrémentons counter sur chaque accès au point de terminaison et en stockant sa valeur dans un attribut de session nommé count .
5. Test de l'application
Testons l'application pour voir si nous sommes réellement capables de stocker les données de session dans MongoDB.
Pour ce faire, nous accéderons au terminal et inspecterons le cookie que nous recevrons. Celui-ci contiendra un identifiant de session.
Après cela, nous interrogerons la collection MongoDB pour récupérer les données de session à l'aide de l'identifiant de session :
@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. Comment ça marche ?
Jetons un coup d'œil à ce qui se passe dans les coulisses de la session de printemps.
Le SessionRepositoryFilter est responsable de la majeure partie du travail :
- convertit la HttpSession dans une MongoSession
- vérifie s'il y a un Cookie présent, et si c'est le cas, charge les données de session depuis le magasin
- enregistre les données de session mises à jour dans le magasin
- vérifie la validité de la session
En outre, le SessionRepositoryFilter crée un cookie avec le nom SESSION c'est HttpOnly et sécurisé. Ce cookie contient l'identifiant de session, qui est une valeur encodée en Base64.
Pour personnaliser le nom ou les propriétés du cookie, nous devrons créer un bean Spring de type DefaultCookieSerializer.
Par exemple, ici nous désactivons le httponly propriété du cookie :
@Bean
public DefaultCookieSerializer customCookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setUseHttpOnlyCookie(false);
return cookieSerializer;
}
7. Détails de la session stockés dans MongoDB
Interrogeons notre collection de sessions à l'aide de la commande suivante dans notre console MongoDB :
db.sessions.findOne()
En conséquence, nous obtiendrons un document BSON similaire à :
{
"_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=")
}
Le _id est un UUID qui sera encodé en Base64 par le DefaultCookieSerializer et défini comme valeur dans la SESSION biscuit. Notez également que le attr l'attribut contient la valeur réelle de notre compteur.