Skip to content

SaveSession GatewayFilter 工厂

SaveSession GatewayFilter 工厂会在将调用转发到下游之前强制执行 WebSession::save 操作。

当使用类似 Spring Session 这样的惰性数据存储时,这特别有用,因为你需要确保在转发调用之前会话状态已被保存。

以下示例配置了一个 SaveSession GatewayFilter:

示例 1. application.yml

yaml
spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: https://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

重要提示: 如果你将 Spring Security 与 Spring Session 集成,并希望确保安全详细信息已转发到远程进程,这一点至关重要。

补充教学 —— 为什么要保存会话?

场景 1:确保会话数据持久化(分布式会话)

  • 背景:使用 Spring Session + Redis 存储会话数据,Redis 采用惰性写入策略(即只在显式调用 save() 时才写入)。
  • 问题:网关在转发请求前,可能已经修改了会话中的某些属性(例如更新了用户权限、添加了临时令牌等),但如果没有显式保存,这些修改可能还在内存中,尚未写入 Redis。
  • 后果:下游服务从 Redis 读取会话时,可能获取到的是旧数据,导致数据不一致。
  • 解决:使用 SaveSession 过滤器,确保在转发请求前,所有会话修改都已持久化到 Redis。
    • 流程:修改会话 → SaveSession 写入 Redis → 转发请求 → 下游服务读取最新数据

场景 2:Spring Security + Spring Session 集成(安全上下文传递)

  • 背景:Spring Security 将认证信息(如用户名、权限等)存储在会话中,Spring Session 将这些信息存储在 Redis 等外部存储中。
  • 问题:当网关认证用户后,安全上下文(SecurityContext)被创建并存储在会话中,但可能尚未持久化到 Redis。
  • 需求:下游服务需要访问用户的认证信息来进行授权检查。
  • 解决SaveSession 确保安全上下文在转发到下游服务之前已保存到 Redis,下游服务可以从 Redis 中读取到正确的认证信息。
    • 配合 SecureHeaders 或其他安全过滤器使用,确保整个安全链路的完整性

场景 3:防止会话丢失(高并发场景)

  • 背景:在高并发场景下,多个请求可能同时修改同一个会话。
  • 问题:如果会话保存操作不是在转发前显式执行,可能会出现竞态条件,导致某些修改丢失。
  • 解决SaveSession 在转发前强制保存,确保当前请求的会话修改不会被后续请求覆盖。
    • 顺序:请求 A 修改会话 → SaveSession 保存 → 转发 → 请求 B 修改会话 → SaveSession 保存 → 转发
    • 这样可以保证每个请求的修改都被正确保存,不会相互覆盖

场景 4:会话生命周期管理

  • 背景:某些业务逻辑需要在请求处理的不同阶段修改会话属性。
  • 需求:确保会话在每次修改后都能及时持久化,避免因应用崩溃或重启导致会话数据丢失。
  • 解决:在关键路由上使用 SaveSession,确保会话数据的及时持久化。
    • 例如:在用户登录、权限变更、购物车更新等关键操作后,立即保存会话

Based on Spring Framework.