= Spring Session - Grails
Eric Helgeson
:toc:

This guide describes how to use Spring Session to transparently leverage Redis to back a web application's `HttpSession` when you use Grails 3.1

NOTE: Grails 3.1 is based off spring boot 1.3, so much of the advanced configuration and options can be found in the Boot docs as well.

NOTE: You can find the completed guid in the <<grails3-sample, Grails 3 sample application>>.

== Updating Dependencies

Before you use Spring Session, you must update your dependencies.
We assume you are working with a working Grails 3.1 web profile.
You must add the following dependencies:

====
.build.gradle
[source,groovy]
[subs="verbatim,attributes"]
----
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-redis'
    compile 'org.springframework.session:spring-session:{spring-session-version}'
}
----
====

ifeval::["{version-snapshot}" == "true"]
Since we use a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
You must have the following in your build.gradle:

====
.build.gradle
[source,groovy]
----
repositories {
    maven {
        url 'https://repo.spring.io/libs-snapshot'
    }
}
----
====
endif::[]

ifeval::["{version-milestone}" == "true"]
Since we use a Milestone version, we need to add the Spring Milestone Maven Repository.
You must have the following in your build.gradle:

====
.build.gradle
[source,groovy]
----
repositories {
    maven {
        url 'https://repo.spring.io/libs-milestone'
    }
}
----
====
endif::[]

[[grails3-redis-configuration]]
== Configuring the Redis Connection

Spring Boot automatically creates a `RedisConnectionFactory` that connects Spring Session to a Redis Server on localhost on port 6379 (default port).
In a production environment you need to ensure to update your configuration to point to your Redis server.
For example, you can include the following in your application.yml:

====
.grails-app/conf/application.yml
[source,yml]
----
spring:
  redis:
    host: localhost
    password: secret
    port: 6397
----
====

For more information, see the https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.

[[grails3-sample]]
== Grails 3 Sample Application

The Grails 3 Sample Application demonstrates how to use Spring Session to transparently leverage Redis to back a web application's `HttpSession` when using Grails.

[[grails3-running]]
=== Running the Grails 3 Sample Application

You can run the sample by obtaining the {download-url}[source code] and invoking the following command:

----
$ ./gradlew :spring-session-sample-misc-grails3:bootRun
----

NOTE:For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost.
See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.

You should now be able to access the application at http://localhost:8080/test/index

[[grails3-explore]]
=== Exploring the `security` Sample Application

You can now 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 that your are logged in with the user entered previously.
The user's information is stored in Redis rather than Tomcat's `HttpSession` implementation.

[[grails3-how]]
=== How Does It Work?

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

When a new `HttpSession` is created, Spring Session creates a cookie named `SESSION` in your browser.
That cookie contains the ID of your session.
You can view the cookies (with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).

You can remove the session by using redis-cli.
For example, on a Linux based system you can type the following:

====
----
	$ redis-cli keys '*' | xargs redis-cli del
----
====

TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].

Alternatively, you can also delete the explicit key.
To do so, enter the following into your terminal, being sure to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your `SESSION` cookie:

====
----
	$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
----
====

Now you can visit the application at http://localhost:8080/test/index and see that we are no longer authenticated.

NOTE: Spring Session does not work with Grails flash scope without additional work.
See https://stackoverflow.com/a/43311427  for an explanation.
