Spring Session - Spring Boot

本指南介绍了在使用 Spring Boot 时如何使用 Spring Session 透明利用 Redis 来支持 Web 应用程序的 HttpSession

This guide describes how to use Spring Session to transparently leverage Redis to back a web application’s HttpSession when you use Spring Boot.

您可以在boot sample application中找到已完成指南。

You can find the completed guide in the boot-sample.

Updating Dependencies

在将 Spring Session 与 Redis 一起使用之前,必须确保拥有正确的依赖项。我们假设你正在与正在运行的 Spring Boot Web 应用程序一起使用。

Before you use Spring Session with Redis, you must ensure that you have the right dependencies. We assume you are working with a working Spring Boot web application.

pom.xml
<dependencies>
	<!-- ... -->

	<dependency>
		<groupId>org.springframework.session</groupId>
		<artifactId>spring-session-data-redis</artifactId>
	</dependency>
</dependencies>
build.gradle
implementation("org.springframework.session:spring-session-data-redis")

Spring Boot 为 Spring Session 模块提供依赖管理,因此您不必明确声明依赖版本。

Spring Boot provides dependency management for Spring Session modules, so you need not explicitly declare dependency version.

Spring Boot Configuration

添加所需依赖项后,我们可以创建我们的 Spring Boot 配置。得益于一流的自动配置支持,只需添加 Spring Boot 依赖项,即可设置 Spring Session,该程序由 Redis 为我们提供支持。

After adding the required dependencies, we can create our Spring Boot configuration. Thanks to first-class auto-configuration support, just by adding the dependency Spring Boot will set up Spring Session backed by Redis for us.

在内部,Spring Boot 应用的配置等效于手动添加 @EnableRedisHttpSession 注释。这将创建一个名称为 springSessionRepositoryFilter 的 Spring Bean,它实现 Filter。该筛选器负责替换 HttpSession 实现,以便由 Spring Session 提供支持。

Under the hood, Spring Boot applies configuration that is equivalent to manually adding @EnableRedisHttpSession annotation. This creates a Spring bean with the name of springSessionRepositoryFilter that implements Filter. The filter is in charge of replacing the HttpSession implementation to be backed by Spring Session.

通过使用 application.properties,可以进行进一步自定义,如下面的清单所示:

Further customization is possible by using application.properties, as the following listing shows:

src/main/resources/application.properties
server.servlet.session.timeout= # Session timeout. If a duration suffix is not specified, seconds is used.
spring.session.redis.flush-mode=on_save # Sessions flush mode.
spring.session.redis.namespace=spring:session # Namespace for keys used to store sessions.

有关更多信息,请参阅 Spring Boot 文档中的 {docs-url}/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] 部分。

For more information, see the {docs-url}/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.

Configuring the Redis Connection

Spring Boot 自动创建一个 RedisConnectionFactory,它将 Spring Session 连接到 localhost 上端口 6379(默认端口)上的 Redis 服务器。在生产环境中,您需要更新配置以指向您的 Redis 服务器。例如,您可以在 application.properties 中包含以下内容:

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 update your configuration to point to your Redis server. For example, you can include the following in your application.properties:

src/main/resources/application.properties
spring.data.redis.host=localhost # Redis server host.
spring.data.redis.password= # Login password of the redis server.
spring.data.redis.port=6379 # Redis server port.

如需获得更多信息,请参阅 Spring Boot 文档的“`HttpSession`到 Redis”({docs-url}/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis)部分。

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

Servlet Container Initialization

我们的 Spring Boot Configuration 创建了一个名为 springSessionRepositoryFilter 的 Spring Bean,该 Bean 实现 FilterspringSessionRepositoryFilter Bean 负责使用由 Spring Session 支持的自定义实现替换 HttpSession

Our boot-spring-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.

为了让 Filter 发挥其作用,Spring 需要加载我们的 Config 类。最后,我们需要确保我们的 Servlet 容器(即 Tomcat)为每个请求使用我们的 springSessionRepositoryFilter。幸运的是,Spring Boot 为我们处理这两步。

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 (that is, Tomcat) uses our springSessionRepositoryFilter for every request. Fortunately, Spring Boot takes care of both of these steps for us.

Boot Sample Application

Boot Sample 应用程序演示了如何使用 Spring Session 将 Redis 透明地利用为 Web 应用程序的 HttpSession 提供支持(当您使用 Spring Boot 时)。

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

Running the Boot Sample Application

您可以获取 源代码 并调用以下命令运行示例:

You can run the sample by obtaining the source code and invoking the following command:

$ ./gradlew :spring-session-sample-boot-redis:bootRun

要让示例发挥作用,你必须在 localhost 上 install Redis 2.8+ 并使用默认端口 (6379) 运行它。或者,你可以更新 RedisConnectionFactory 以指向 Redis 服务器。另一个选项是使用 Docker 在 localhost 上运行 Redis。有关详细说明,请参见 Docker Redis repository

For the sample to work, you must 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 Docker to run Redis on localhost. See Docker Redis repository for detailed instructions.

您现在应该能够访问 [role="bare"][role="bare"]http://localhost:8080/ 中的应用程序。

You should now be able to access the application at [role="bare"]http://localhost:8080/

Exploring the security Sample Application

现在,您可以尝试使用该应用程序。输入以下内容进行登录:

Now you can try using the application. Enter the following to log in:

  • Username user

  • Password password

现在,单击 Login 按钮。现在,您应该会看到一条消息,提示您已使用之前输入的用户名登录。用户的的信息存储在 Redis 中,而不是 Tomcat 的 HttpSession 中。

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

How Does It Work?

我们不使用 Tomcat 的 HttpSession,而将值存储在 Redis 中。Spring 会话使用由 Redis 支持的实现替换 HttpSession。当 Spring 安全性的 SecurityContextPersistenceFilterSecurityContext 保存到 HttpSession 中时,其随后将存储在 Redis 中。

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.

当创建新的 HttpSession 时,Spring Session 在浏览器中创建一个名为 SESSION 的 cookie。该 cookie 包含会话 ID。您可以查看 cookie(使用 ChromeFirefox)。

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 Chrome or Firefox).

你可以使用 redis-cli 删除会话。例如,在基于 Linux 的系统上,你可以输入以下内容:

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

Redis 文档包含有关 installing redis-cli 的说明。

The Redis documentation has instructions for installing redis-cli.

或者,您还可以删除显式密钥。为此,请将以下内容输入到您的终端中,确保将 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e 替换为 SESSION cookie 的值:

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

现在你可以访问位于 [role="bare"][role="bare"]http://localhost:8080/ 的应用,并观察我们不再处于经过身份验证状态。

Now you can visit the application at [role="bare"]http://localhost:8080/ and observe that we are no longer authenticated.