MongoDBとの春のセッション

1. 概要

このクイックチュートリアルでは、Spring Bootの有無にかかわらず、https://www.baeldung.com/spring-data-mongodb-tutorial [MongoDB]でサポートされたSpringセッションの使用方法について説明します。
Spring Sessionは、https://www.baeldung.com/spring-session [Redis]やlink:/spring-session-jdbc[JDBC]などの他のストアを使用してバックアップすることもできます。

2. スプリングブート構成

最初に、Spring Bootに必要な依存関係と構成を見てみましょう。 はじめに、https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework.session%22%20AND%20a%3A%22spring-sessionの最新バージョンを追加しましょう-data-mongodb%22 [_spring-session-data-mongodb_]および_https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a %3A%22spring-boot-starter-data-mongodb%22 [spring-boot-starter-data-mongodb] _プロジェクトへ:
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-mongodb</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>
その後、Spring Bootの自動構成を有効にするには、_application.properties_で_mongodb_としてSpring Sessionストアタイプを追加する必要があります。
spring.session.store-type=mongodb

*3. Spring Boot *を使用しないSpring設定

ここで、Spring Bootを使用せずにMongoDBにSpringセッションを保存するために必要な依存関係と構成を見てみましょう。
Spring Boot構成と同様に、_spring-session-data-mongodb_依存関係が必要です。 ただし、ここではhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.springframework.data%22%20AND%20a%3A%22spring-data-mongodbを使用しますMongoDBデータベースにアクセスするための%22 [_spring-data-mongodb_]依存関係:
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-mongodb</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>
最後に、アプリケーションの構成方法を見てみましょう。
@EnableMongoHttpSession
public class HttpSessionConfig {

    @Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
        return new JdkMongoSessionConverter(Duration.ofMinutes(30));
    }
}
  • @ EnableMongoHttpSession annotationは、セッションデータをMongoDBに保存するために必要な構成を有効にします*。

    また、_JdkMongoSessionConverter_がセッションデータのシリアル化と逆シリアル化を行うことに注意してください。

4. サンプルアプリケーション

構成をテストするアプリケーションを作成しましょう。 Spring Bootを使用するのは、より高速で、必要な構成が少ないためです。
まず、リクエストを処理するコントローラーを作成します。
@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);
    }
}
この例でわかるように、エンドポイントへのヒットごとに_counter_をインクリメントし、その値を_count_という名前のセッション属性に格納しています。

5. アプリケーションのテスト

アプリケーションをテストして、セッションデータを実際にMongoDBに保存できるかどうかを確認しましょう。
そのために、エンドポイントにアクセスし、受信するCookieを検査します。 これにはセッションIDが含まれます。
その後、セッションIDを使用してセッションデータを取得するためにMongoDBコレクションをクエリします。
@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. どのように機能しますか?

舞台裏のSpringセッションで何が起こっているのか見てみましょう。
_SessionRepositoryFilter_は、ほとんどの作業を担当します。
  • _HttpSession_を_MongoSession_に変換します

  • Cookieがあるかどうかを確認します
    存在し、存在する場合、ストアからセッションデータをロードします

  • 更新されたセッションデータをストアに保存します

  • セッションの有効性を確認します

    また、__ SessionRepositoryFilter __は、__ SESSION ___thatという名前のCookieOnlyを作成し、HttpOnlyで安全です。 このCookieには、Base64でエンコードされた値であるセッションIDが含まれています。
  • Cookieの名前またはプロパティをカスタマイズするには、DefaultCookieSerializer . *型のSpring Beanを作成する必要があります

    たとえば、ここではCookieの_httponly_プロパティを無効にします。
@Bean
public DefaultCookieSerializer customCookieSerializer(){
    DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();

    cookieSerializer.setUseHttpOnlyCookie(false);

    return cookieSerializer;
}

7. MongoDBに保存されているセッションの詳細

MongoDBコンソールで次のコマンドを使用して、セッションコレクションを照会します。
db.sessions.findOne()
その結果、次のようなlink:/mongodb-bson[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 __はlink:/java-uuid[UUID]であり、_DefaultCookieSerializer_によってBase64エンコードされ、_SESSION_ Cookieの値として設定されます。 また、_attr_属性にはカウンターの実際の値が含まれていることに注意してください。

8. 結論

このチュートリアルでは、分散システムでHTTPセッションを管理するための強力なツールであるMongoDBを使用したSpring Sessionについて説明しました。 この目的を念頭に置いて、アプリケーションの複数のインスタンスにまたがってセッションを複製する問題を解決するのに非常に役立ちます。
いつものように、ソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-session[GitHub上]で入手できます。