会话丢失并在每个 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.com
为 com
设置 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 请求中创建为新的的主要内容,如果未能解决你的问题,请参考以下文章