1. 개요

이 빠른 사용방법(예제)에서는 Spring Boot를 사용하거나 사용하지 않고 MongoDB로 지원되는 Spring Session을 사용하는 방법을 탐색 할 것 입니다.

Spring Session은 RedisJDBC 와 같은 다른 저장소와 함께 지원 될 수도 있습니다 .

2. 스프링 부트 설정

먼저 Spring Boot에 필요한 의존성과 구성을 살펴 보겠습니다. 먼저 최신 버전의 spring-session-data-mongodbspring-boot-starter-data-mongodb 를 프로젝트에 추가하겠습니다.

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

그 후 Spring Boot 자동 구성을 활성화 하려면 application.properties에 Spring Session 저장소 유형을 mongodb 로 추가해야 합니다 .

spring.session.store-type=mongodb

3. 스프링 부트없이 스프링 설정

이제 Spring Boot없이 MongoDB에 Spring 세션을 저장하는 데 필요한 의존성 및 구성을 살펴 보겠습니다.

Spring Boot 구성과 유사하게 spring-session-data-mongodb 의존성 이 필요합니다 . 그러나 여기에서는 Spring-data-mongodb 의존성을 사용하여 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>

마지막으로 애플리케이션을 구성하는 방법을 살펴 보겠습니다.

@EnableMongoHttpSession
public class HttpSessionConfig {

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

에서 @ EnableMongoHttpSession의 어노테이션 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);
    }
}

이 예에서 볼 수 있듯이 엔드 포인트에 대한 모든 적중에 대해 카운터증가 시키고 해당 값을 count 라는 세션 속성에 저장합니다 .

5. 응용 프로그램 테스트

MongoDB에 세션 데이터를 실제로 저장할 수 있는지 애플리케이션을 테스트 해 보겠습니다.

이를 위해 엔드 포인트에 액세스하고 수신 할 쿠키를 검사합니다. 여기에는 세션 ID가 포함됩니다.

그 후 MongoDB 컬렉션을 쿼리하여 세션 ID를 사용하여 세션 데이터를 가져옵니다.

@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는 대부분의 작업을 담당합니다 :

  • HttpSessionMongoSession 으로 변환합니다.
  • 쿠키 가 있는지 확인하고 존재하는 경우 저장소에서 세션 데이터를로드합니다.
  • 업데이트 된 세션 데이터를 저장소에 저장합니다.
  • 세션의 유효성을 확인합니다.

또한 SessionRepositoryFilter 는 HttpOnly이고 안전한 SESSION 이라는 이름의 쿠키를 만듭니다 . 이 쿠키에는 Base64로 인코딩 된 값인 세션 ID가 포함되어 있습니다.

쿠키 이름 또는 속성을 사용자 지정하려면 DefaultCookieSerializer 유형의 Spring Bean을 만들어야합니다 .

예를 들어, 여기 에서는 쿠키 httponly 속성을 비활성화합니다 .

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

7. MongoDB에 저장된 세션 정보

MongoDB 콘솔에서 다음 명령을 사용하여 세션 컬렉션을 쿼리 해 보겠습니다.

db.sessions.findOne()

결과적 으로 다음과 유사한 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가 A는 UUID 에 의해 64 비트로 인코딩 될 DefaultCookieSerializer 상기의 값으로 설정 세션 쿠키. 또한 attr 속성에는 카운터의 실제 값이 포함되어 있습니다.

8. 결론

이 예제에서 우리는 분산 시스템에서 HTTP 세션을 관리하기위한 강력한 도구 인 MongoDB로 지원되는 Spring Session을 살펴 보았습니다. 이러한 목적을 염두에두고 애플리케이션의 여러 인스턴스 에서 세션을 복제하는 문제를 해결하는 데 매우 유용 할 수 있습니다 .

평소처럼 소스 코드는 GitHub에서 사용할 수 있습니다 .