什么可能导致 session ID 在重定向后有时会发生变化(Java/Kotlin Spring 网络应用程序)?

What might cause a session ID to sometimes change after redirect (Java/Kotlin Spring web app)?

我有一个使用 Kotlin+Spring 构建的 Web 应用程序,它通过 session ID 识别用户。在静态首页上,我有一个表单,在提交时向“/start”发送一个 POST 请求。这是由 Spring 通过执行一些代码并将用户重定向到另一个页面“/page”来处理的——这是最少的代码:

@Controller
class SomeController() {
    // No GetMapping("/"), because '/' is 100% static

    @PostMapping("/start")
    fun start(@ModelAttribute someModelAttr: SomeModelAttr, model: Model,
              response: HttpServletResponse,
              session: HttpSession) {
        log.info { "POST /start visited by ${session.id}" }
        val id = getSomeStuffSynchronously(someModelAttr, session.id);
        response.sendRedirect("page/${id}")
    }

    @GetMapping("/page/{id}")
    fun page(@PathVariable id: String,
             model: Model,
             session: HttpSession) {
        log.info { "GET /page/${id} visited by ${session.id}" }
        doOtherStuff(id, session.id);
        return "page" // i.e. render a Thymeleaf template
    }

上面的代码假设startpage中的session ID是一样的。然而,有时(但不总是)这是错误的,这会破坏用户的东西。在这种情况下,日志行基本上是:

POST /start visited by abcd
Log from getSomeStuffSynchronously(someModelAttr, "abcd")
GET /page/123 visited by vxyz

不幸的是,发生这种情况时,我无法捕获浏览器发送和接收的 headers,因为当我尝试时,我无法重现此问题。 我检查过:

会话是 Cookie session,由 spring-session-redis 管理,Redis 中的超时设置为 15 分钟。但是,我没有发现访问该站点的时间与此问题发生之间有任何明显的相关性。

我的问题是:什么可能导致 session ID 在重定向期间发生变化?

依赖 session.id 在重定向之间是不可靠的,但作为一种变通方法,可以使用 RedirectAttributes 并将第二个请求处理程序中需要的相关数据存储为 flash 属性——参见例如

获得不同会话的原因可能是因为 cookie/url 包含对会话的引用的参数可能未被 set/is 使用(因此每次都会生成一个新会话)。

这可能是一个显而易见的问题,但您确定负责处理会话的过滤器已注册吗?例如。您是否将 @EnableRedisHttpSession 注释添加到配置 class(参见 redig http session docs)?