1. Przegląd
W tym krótkim samouczku dowiemy się, jak używać Spring Session wspieranej przez MongoDB, zarówno z Spring Boot, jak i bez niego.
Spring Session można również wspierać w innych sklepach, takich jak Redis i JDBC.
2. Konfiguracja rozruchu sprężynowego
Najpierw spójrzmy na zależności i konfigurację wymaganą dla Spring Boot. Na początek dodajmy najnowsze wersje spring-session-data-mongodb i wiosenny-boot-starter-data-mongodb do naszego projektu:
<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>
Następnie, aby włączyć automatyczną konfigurację Spring Boot, musimy dodać typ sklepu Spring Session jako mongodb w application.properties :
spring.session.store-type=mongodb
3. Konfiguracja sprężynowa bez sprężynowego rozruchu
Przyjrzyjmy się teraz zależnościom i konfiguracji wymaganej do przechowywania sesji Spring w MongoDB bez Spring Boot.
Podobnie jak w przypadku konfiguracji Spring Boot, będziemy potrzebować spring-session-data-mongodb zależność. Jednak tutaj użyjemy spring-data-mongodb zależność dostępu do naszej bazy danych 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>
Na koniec zobaczmy, jak skonfigurować aplikację:
@EnableMongoHttpSession
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter(Duration.ofMinutes(30));
}
}
@EnableMongoHttpSession adnotacja umożliwia konfigurację wymaganą do przechowywania danych sesji w MongoDB .
Pamiętaj też, że JdkMongoSessionConverter jest odpowiedzialny za serializację i deserializację danych sesji.
4. Przykładowa aplikacja
Stwórzmy aplikację do testowania konfiguracji. Będziemy używać Spring Boot, ponieważ jest szybszy i wymaga mniej konfiguracji.
Zaczniemy od utworzenia kontrolera do obsługi żądań:
@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);
}
}
Jak widać na tym przykładzie, zwiększamy licznik przy każdym trafieniu do punktu końcowego i zapisując jego wartość w atrybucie sesji o nazwie count .
5. Testowanie aplikacji
Przetestujmy aplikację, aby zobaczyć, czy rzeczywiście jesteśmy w stanie przechowywać dane sesji w MongoDB.
Aby to zrobić, uzyskamy dostęp do punktu końcowego i sprawdzimy plik cookie, który otrzymamy. Będzie zawierać identyfikator sesji.
Następnie wyślemy zapytanie do kolekcji MongoDB, aby pobrać dane sesji przy użyciu identyfikatora sesji:
@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. Jak to działa?
Przyjrzyjmy się, co dzieje się za kulisami sesji wiosennej.
SessionRepositoryFilter odpowiada za większość prac:
- konwertuje HttpSession w MongoSession
- sprawdza, czy istnieje plik cookie obecny, a jeśli tak, ładuje dane sesji ze sklepu
- zapisuje zaktualizowane dane sesji w sklepie
- sprawdza ważność sesji
Ponadto SessionRepositoryFilter tworzy plik cookie o nazwie SESJA to jest HttpOnly i bezpieczne. Ten plik cookie zawiera identyfikator sesji, który jest wartością zakodowaną w Base64.
Aby dostosować nazwę lub właściwości pliku cookie, musimy utworzyć ziarenko Spring typu DefaultCookieSerializer.
Na przykład tutaj wyłączamy tylko http właściwość pliku cookie:
@Bean
public DefaultCookieSerializer customCookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setUseHttpOnlyCookie(false);
return cookieSerializer;
}
7. Szczegóły sesji przechowywane w MongoDB
Przeszukajmy naszą kolekcję sesji za pomocą następującego polecenia w naszej konsoli MongoDB:
db.sessions.findOne()
W rezultacie otrzymamy dokument BSON podobny do:
{
"_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 to identyfikator UUID, który będzie zakodowany w Base64 przez DefaultCookieSerializer i ustaw jako wartość w SESJI ciastko. Zwróć też uwagę, że atr atrybut zawiera rzeczywistą wartość naszego licznika.