Spring Session - Spring Boot
本指南描述在使用 Spring Boot 时,如何使用 Spring Session 透明地利用 Redis 来支撑 Web 应用程序的 HttpSession。
你可以在 Boot 示例应用程序 中找到完整的指南。
更新依赖
在将 Spring Session 与 Redis 结合使用之前,你必须确保拥有正确的依赖。我们假设你正在使用一个可运行的 Spring Boot Web 应用程序。
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-session-data-redis</artifactId>
</dependency>
</dependencies>
implementation("org.springframework.boot:spring-boot-starter-session-data-redis")
Spring Boot 为 Spring Session 模块提供依赖管理,因此你无需显式声明依赖版本。
Spring Boot 配置
添加所需依赖后,我们可以创建 Spring Boot 配置。得益于一流的自动配置支持,只需添加依赖,Spring Boot 就会为我们设置由 Redis 支撑的 Spring Session。
在底层,Spring Boot 应用的配置等同于手动添加 @EnableRedisHttpSession 注解。这会创建一个名为 springSessionRepositoryFilter、实现 Filter 的 Spring bean。该过滤器负责将 HttpSession 实现替换为由 Spring Session 支撑。
可以使用 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 文档的 Spring Session 部分。
配置 Redis 连接
Spring Boot 会自动创建一个 RedisConnectionFactory,将 Spring Session 连接到 localhost 上端口 6379(默认端口)的 Redis 服务器。在生产环境中,你需要更新配置以指向你的 Redis 服务器。例如,你可以在 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 文档的连接到 Redis 部分。
Servlet 容器初始化
我们的 Spring Boot 配置 创建了一个名为 springSessionRepositoryFilter、实现 Filter 的 Spring bean。springSessionRepositoryFilter bean 负责将 HttpSession 替换为由 Spring Session 支撑的自定义实现。
为了让我们的 Filter 发挥作用,Spring 需要加载我们的 Config 类。最后,我们需要确保 servlet 容器(即 Tomcat)对每个请求都使用我们的 springSessionRepositoryFilter。幸运的是,Spring Boot 为我们处理了这两个步骤。
Boot 示例应用程序
Boot 示例应用程序演示了在使用 Spring Boot 时,如何使用 Spring Session 透明地利用 Redis 来支撑 Web 应用程序的 HttpSession。
运行 Boot 示例应用程序
你可以通过获取源代码并运行以下命令来启动示例:
$ ./gradlew :spring-session-sample-boot-redis:bootRun
要使示例正常工作,你必须在 localhost 上安装 Redis 2.8+ 并以默认端口(6379)运行。或者,你可以更新 RedisConnectionFactory 以指向 Redis 服务器。另一个选择是使用 Docker 在 localhost 上运行 Redis。详细说明请参阅 Docker Redis 仓库。
现在你应该可以通过 localhost:8080/ 访问该应用程序了。
探索 security 示例应用程序
现在你可以尝试使用该应用程序。输入以下内容进行登录:
- 用户名 user
- 密码 password
现在点击 Login 按钮。你现在应该会看到一条消息,指示你已使用先前输入的用户登录。用户信息存储在 Redis 中,而不是 Tomcat 的 HttpSession 实现中。
它是如何工作的?
我们没有使用 Tomcat 的 HttpSession,而是将值持久化到 Redis 中。Spring Session 将 HttpSession 替换为由 Redis 支撑的实现。当 Spring Security 的 SecurityContextPersistenceFilter 将 SecurityContext 保存到 HttpSession 时,它随后被持久化到 Redis 中。
你可以使用 redis-cli 移除会话。例如,在基于 Linux 的系统上,你可以输入以下内容:
$ redis-cli keys '*' | xargs redis-cli del
Redis 文档中有安装 redis-cli 的说明。
或者,你也可以删除显式键。为此,在终端中输入以下内容,并确保将 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e 替换为你的 SESSION cookie 的值:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
现在你可以访问 localhost:8080/ 上的应用程序,并观察到我们已不再处于认证状态。