会话丢失并在每个 servlet 请求中创建为新的

Posted

技术标签:

【中文标题】会话丢失并在每个 servlet 请求中创建为新的【英文标题】:Session is lost and created as new in every servlet request 【发布时间】:2011-01-09 10:37:37 【问题描述】:

我有这个大问题。每次我向服务器发出新请求时,我的当前会话都会消失。

我已经检查了很多地方。我找不到问题所在。我也包括了 Tomcat 和应用程序中 web.xml 中的 session-config。我还允许我的浏览器接受 cookie。在每个浏览器中测试。它不工作。

我只是在使用 JSP/Servlet 开发一个简单的 java ee 应用程序。我只有在服务器机器上部署到 tomcat 后才会遇到问题。

【问题讨论】:

小问题:***.com/q/13461838/698168 【参考方案1】:

造成这种情况的一个可能原因是具有“裸”主机名(即没有域部分的主机名)。如果您在 Intranet 中工作,这很常见。

问题是几乎所有浏览器的 cookie 都不会接受没有域名的主机名的 cookie。这样做是为了防止 evilsite.comcom 设置 Cookie(这很糟糕,因为这将是最终的跟踪 cookie)。

因此,如果您通过 http://examplehost/ 访问您的应用程序,它将不会接受任何 cookie,而对于 http://examplehost.localdomain/,它将接受(并返回)cookie 就好了。

令人讨厌的是,服务器无法区分“浏览器获取 cookie 并忽略它”和“浏览器从未获取 cookie”。因此,每次访问对服务器来说都像是一个全新的会话。

【讨论】:

我已经在使用本地主机的服务器中测试了该应用程序。它引起了同样的问题。在这个项目中,我使用 Jersey REST 服务、JCaptcha 和自定义标签。 很奇怪的是,我在服务器上安装了Glassfish,并将应用程序部署在glassfish上。还是同样的问题……我完全迷路了。 我已将我的机器链接名称从 IP 更改为 machinene.localdomain,我的问题已解决!。谢谢 我在 localhost 和 Chrome 中遇到了这个问题。奇怪的是,当重新启动或刚刚重置其设置时,浏览器接受了 localhost 的 cookie。但是,在第一次从应用程序注销后,它停止了这样做。解决方案是使用 localhost.localdomain 代替。谢谢!【参考方案2】:

多年后,我再也没有在这里发布答案。当时我很忙,忘记了这个问题。但是,今天我像往常一样在 *** 中寻找解决方案,并看到这个通知提到我从这个问题中得到积分。似乎其他开发人员也面临同样的问题。所以,我试着回忆我是如何解决这个问题的。是的,我通过手动放回会话 ID 来跟踪/维护会话 ID 来解决。

请查看我在 servlet 中手动放回 jsessionid 的代码。

HttpSession session = request.getSession();
if (request.getParameter("JSESSIONID") != null) 
    Cookie userCookie = new Cookie("JSESSIONID", request.getParameter("JSESSIONID"));
    response.addCookie(userCookie);
 else 
    String sessionId = session.getId();
    Cookie userCookie = new Cookie("JSESSIONID", sessionId);
    response.addCookie(userCookie);

【讨论】:

【参考方案3】:

首先检查 webapp 的 context.xml 是否没有配置了 cookies="false"

此外,很高兴知道 cookie 依赖于域、端口和上下文路径。如果页面中的链接指向 不同 域、端口和/或上下文路径,而不是当前请求 URL(您在浏览器地址栏中看到的那个),那么 cookie 将不会通过这将导致无法再识别会话,因此您将从 servletcontainer 获得一个新的。

如果这不是原因,请检查您是否出于某种原因没有对每个请求进行重定向。如果您在第一个请求中就已经这样做了,那么 cookie 将会丢失。你需要更换

response.sendRedirect(url);

通过

response.sendRedirect(response.encodeRedirectURL(url));

【讨论】:

是的。这让我发疯了。谢谢BalusC。 有人能解释一下为什么会这样吗?它特别是关于sendRedirect 的说明?没时间就不用在这里解释了,你指点我就看文档。 @DavidS:它将会话 ID 添加到 URL,以便服务器可以通过传入请求的 URL 而不是 cookie 来识别关联的会话。另见***.com/q/1700390 response.sendRedirect(response.encodeRedirectURL(url));也为我工作。谢谢BalusC。【参考方案4】:

在您的属性中

  server.session.cookie.http-only=true
  server.session.cookie.secure=true

删除这些设置,它将保留您的会话 id cookie,每次请求都会重置。

【讨论】:

感谢帮助,对于那些在属性文件中没有这些的人,我在 web.xml 中有 em。【参考方案5】:

由于 secure 标志,我遇到了陈旧的 https 会话 cookie(我的临时术语)问题。

我在 http 和 https 之间切换时遇到了这个问题。 https 会话存储的 cookie 永远不会被 http 会话覆盖。它永远留在了 FireFox 的记忆中。它在 FireFox 工具/选项/隐私/删除单个 cookie 中可见,而在 Send for 字段中仅用于安全连接。清除此单个 cookie 或所有 cookie 是一种解决方法。

我在用wget调试问题,发现有这样一个header:

Set-Cookie: JSESSIONID=547ddffae0e5c0e2d1d3ef21906f; Path=/myapp; Secure; HttpOnly

安全一词仅出现在 https 连接中并创建此陈旧的 cookie。这是一个 SecureFlag(参见 OWASP)。有一些方法可以在服务器端禁用此标志,这似乎是一个永久的解决方案,但可能并不安全。

或者是浏览器的错误,cookie没有被覆盖?

【讨论】:

【参考方案6】:

尝试将 Live Http Headers plugin 添加到 firefox,并确保会话 cookie 确实从服务器传递到浏览器,并确保浏览器在下一次请求时再次将其发送回来。

【讨论】:

但是,怎么做?我在很多项目中使用了会话。我从来没有遇到过这个问题。你能告诉我如何将它发送回浏览器吗?这不仅发生在 Firefox 中,也发生在其他浏览器中。 我并不是说它与浏览器相关,但该插件将允许您查看来回传递的 cookie(或不传递,视情况而定)。它不会告诉你为什么,但它可能会告诉你什么 我在发布 Set-Cookie 时得到了这个:JSESSIONID=D02AE9722D84B1E404C80125F5CD23BF; Path=/myapp 刷新页面后我得到了这个。设置 Cookie:JSESSIONID=F23780E7F8085624EBF25F3EB3DFF45D;路径=/myapp【参考方案7】:

请验证会话是否未在您的代码中的某个位置失效。寻找类似request.getSession().invalidate();的代码

【讨论】:

我已经检查过了。实际上,它在我的开发机器上运行良好,但是在服务器中 在这种情况下,您的开发服务器和实时服务器之间的配置显然存在差异。请将您修改的 web.xml sn-ps 添加到您的问题中。【参考方案8】:

如果有负载平衡配置,则必须在网络中配置一个路由,以将请求保留在同一服务器中。否则,每个请求将转到不同的服务器,从而丢失会话属性。

【讨论】:

【参考方案9】:

编辑您的 tomcat context.xml 文件并将 <Context> 标记替换为 <Context useHttpOnly="false"> ,这对我有帮助。

【讨论】:

【参考方案10】:

您是通过 http 还是 https 连接? 对于 servlet,会话我的 cookie 具有“安全”和“httpOnly”属性。 “安全”表示用户代理仅在传输安全 (https/tls) 时才会发送 cookie。如果您使用 http 连接,则会在每个请求上创建一个新会话。 'httpOnly' 表示客户端脚本不能修改 cookie。

【讨论】:

以上是关于会话丢失并在每个 servlet 请求中创建为新的的主要内容,如果未能解决你的问题,请参考以下文章

AEM 中的 Servlet,POST 请求中的正文丢失

如何在Glassfishv4上的另一个Servlet中创建的Servlet中恢复会话?

7Servlet会话跟踪

servlet 和 jsp 中的会话跟踪

跨域请求,关于后端session会话丢失的解决办法

跨越请求,关于后端session会话丢失的解决办法(转载)