# Spring Session - MongoDB Repositories

This guide describes how to use Spring Session backed by MongoDB.

|   |The completed guide can be found in the [mongo sample application](#mongo-sample).|
|---|----------------------------------------------------------------------------------|

[Index](../index.html)

## Updating Dependencies

Before you use Spring Session MongoDB, you must ensure to update your dependencies.
We assume you are working with a working Spring Boot web application.
If you are using Maven, ensure to add the following dependencies:

pom.xml

```
<dependencies>
	<!-- ... -->
	<dependency>
		<groupId>org.springframework.session</groupId>
		<artifactId>spring-session-data-mongodb</artifactId>
	</dependency>
</dependencies>
```

Since We are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:

pom.xml

```
<repositories>
	<!-- ... -->
	<repository>
		<id>spring-snapshot</id>
		<url>https://repo.spring.io/libs-snapshot</url>
	</repository>
</repositories>
```

## Spring Configuration

After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.

All you have to do is to add the following Spring Configuration:

```
@EnableMongoHttpSession (1)
public class HttpSessionConfig {

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

}
```

|**1**|The `@EnableMongoHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.<br/>This filter is what replaces the default `HttpSession` with the MongoDB-backed bean.|
|-----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|**2**|                                                                                         Configures the session timeout to 30 minutes.                                                                                          |

## Configuring the MongoDB Connection

Spring Boot automatically creates a `MongoClient` that connects Spring Session to a MongoDB Server on localhost on port 27017 (default port).
In a production environment you need to ensure to update your configuration to point to your MongoDB server.
For example, you can include the following in your **application.properties**

src/main/resources/application.properties

```
spring.data.mongodb.host=mongo-srv
spring.data.mongodb.port=27018
spring.data.mongodb.database=prod
```

For more information, refer to [Connecting to MongoDB](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-connecting-to-mongodb) portion of the Spring Boot documentation.

## Servlet Container Initialization

Our [Spring Configuration](#boot-mongo-configuration) created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.

In order for our `Filter` to do its magic, Spring needs to load our `Config` class.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Boot takes care of both of these steps for us.

## MongoDB Sample Application

The MongoDB Sample Application demonstrates how to use Spring Session to transparently leverage MongoDB to back a web application’s `HttpSession` when using Spring Boot.

### Running the MongoDB Sample Application

You can run the sample by obtaining the [source code](https://github.com/spring-projects/spring-session/archive/main.zip) and invoking the following command:

```
$ ./gradlew :samples:mongo:bootRun
```

You should now be able to access the application at [http://localhost:8080/](http://localhost:8080/)

### Exploring the security Sample Application

Try using the application. Enter the following to log in:

* **Username** *user*

* **Password** *password*

Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
The user’s information is stored in MongoDB rather than Tomcat’s `HttpSession` implementation.

### How does it work?

Instead of using Tomcat’s `HttpSession`, we are actually persisting the values in Mongo.
Spring Session replaces the `HttpSession` with an implementation that is backed by Mongo.
When Spring Security’s `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Mongo.

When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with [Chrome](https://developer.chrome.com/devtools/docs/resources#cookies) or [Firefox](https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List)).

If you like, you can easily inspect the session using mongo client. For example, on a Linux based system you can type:

|   |The sample application uses an embedded MongoDB instance that listens on a randomly allocated port.<br/>The port used by embedded MongoDB together with exact command to connect to it is logged during application startup.|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

```
$ mongo --port ...
> use test
> db.sessions.find().pretty()
```

Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `60f17293-839b-477c-bb92-07a9c3658843` with the value of your SESSION cookie:

```
> db.sessions.remove({"_id":"60f17293-839b-477c-bb92-07a9c3658843"})
```

Now visit the application at [http://localhost:8080/](http://localhost:8080/) and observe that we are no longer authenticated.