我有一个用kotlin+spring构建的web应用程序,它通过会话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
}
上面的代码假设会话id start
以及 page
是一样的。然而,有时(但不总是)这是错误的,这打破了用户的东西。在这种情况下,日志行基本上是:
POST /start visited by abcd
Log from getSomeStuffSynchronously(someModelAttr, "abcd")
GET /page/123 visited by vxyz
不幸的是,发生这种情况时,我无法捕获浏览器发送和接收的标头,因为当我尝试时,我无法重现此问题。我查过了:
无论用户是否在浏览器中使用匿名模式,都可能发生此问题
除了首页->/start->/page/id之外,我还没有在其他请求中观察到这种情况
我没有缓存启用,无论是在我的主机供应商或在 Spring
我在我的网站上没有一个巨大的负载
我不使用spring security
会话是cookie会话,由spring会话redis管理,redis中的超时设置为15分钟。然而,我没有看到任何明显的相关性之间的时间访问该网站和这个问题的发生。
我的问题是:在重定向过程中,什么可能导致会话id发生更改?
2条答案
按热度按时间f8rj6qna1#
获取不同会话的原因可能是因为没有设置/使用包含会话引用的cookie/url参数(因此每次都会生成一个新会话)。
这可能是一个显而易见的问题,但您确定负责处理会话的筛选器已注册吗?e、 g.你添加了
@EnableRedisHttpSession
配置类的注解(请参阅redig http会话文档)?mbskvtky2#
在重定向之间依赖session.id是不可靠的,但是作为一种解决方法,可以使用
RedirectAttributes
并将第二个请求处理程序中所需的相关数据存储为flash属性——例如,请参见如何在spring中将模型作为重定向属性传递