什么可能导致会话ID有时改变后重定向(Java/Kotlin Spring web应用程序)?



我有一个用Kotlin+Spring构建的web应用程序,它通过会话ID标识用户。在静态首页上,我有一个表单,在提交时,发送POST请求到"/start"Spring通过执行一些代码并将用户重定向到另一个页面来处理这个问题。-这里是最小的代码:

@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中的会话ID相同。然而,有时(但并非总是如此)这是错误的,这会破坏用户的东西。在这种情况下,日志行基本上是:

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

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

  • 无论用户是否在浏览器中使用隐身模式,这个问题都可能发生
  • 除了首页->/start->/page/id
  • 之外,我还没有在其他请求中观察到这种情况。
  • 我的主机提供商和Spring都没有启用缓存
  • 我的网站没有很大的负载
  • 我不使用spring-security

会话是Cookie会话,由spring-session-redis管理,Redis中的超时时间设置为15分钟。但是,我没有看到访问网站的时间间隔与这个问题发生之间有任何明显的关联。

我的问题是:什么可能导致会话ID在重定向期间改变?

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

这可能是一个明显的问题,但是你确定负责处理会话的过滤器已注册吗?例如,你是否将@EnableRedisHttpSession注释添加到配置类(参见redg http会话文档)?

依赖会话。id在重定向之间是不可靠的,但是作为一种解决方法,可以使用RedirectAttributes并存储在第二个请求处理程序中需要的相关数据作为flash属性-参见例如如何将模型作为重定向属性传递给spring

最新更新