【问题标题】:cookies with <path>/</path> and JSESSIONID带有 <path>/</path> 和 JSESSIONID 的 cookie
【发布时间】:2017-04-06 19:55:48
【问题描述】:

我正在尝试将我应用程序的 web.xml 中的 cookie 路径(如建议的here)设置为:

<session-config>
    <cookie-config>
        <path>/</path>
    </cookie-config>
</session-config>

所以我将两个相同的 Web 应用程序分别部署到 localhost:8080/application-alocalhost:8080/application-b

每个应用程序都是一个 servlet:

public class ControllerServlet extends HttpServlet{
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
      HttpSession session = req.getSession(false);

      if (session == null) {
          session = req.getSession(true);
          System.out.printf("No session was present - new one created with JSESSIONID=[%s]\n", session.getId());
      } else {
          System.out.printf("JSESSIONID cookie was present and HttpSession objects exists with JSESSIONID=[%s]\n", session.getId());
      }
  }
}

我将应用程序部署到 Tomcat 8.5 容器(也尝试使用 Tomcat 9,行为相同)。当我使用浏览器访问application-a 时,我看到的是:

…在我阅读的 Tomcat 日志中:

No session was present - new one created with JSESSIONID=[A227B147A4027B7C37D31A4A62104DA9]

到目前为止一切顺利。然后当我访问application-b 时,我看到的是:

… Tomcat 日志显示:

No session was present - new one created with JSESSIONID=[5DC8554459233F726628875E22D57AD5]

这也很好解释 herein this answer 我引用:

SRV.7.3 会话范围

HttpSession 对象必须在应用程序(或 servlet 上下文)级别。底层机制,例如用于 建立会话,对于不同的上下文可以是相同的,但是 引用的对象,包括该对象中的属性,绝不能 由容器在上下文之间共享。

因此,即使在请求中存在 JSESSIONID cookie,我的应用程序(部署在 application-b 中的应用程序)也无法在其自己的 servlet 上下文范围内找到 HttpSession 对象,因此创建了一个新的会话对象,并为 JSESSIONID cookie 分配了一个新值。

但是,当我现在回到我的 application-a 时,我发现由于为 cookie 路径配置了 / 值,它现在正在尝试使用由 application-b 设置的 JSESSIONID 值和当然,它的 servlet 在它自己的上下文 (application-a) 中找不到这样的会话对象,因此创建了 JSESSIONID cookie 的新值,这反过来将使 application-b 应用程序的会话无效,依此类推,当我在两个应用程序之间来回切换时,以此类推。

所以我的问题是:

1 鉴于上述行为,两个应用程序似乎不可能使用相同的JSESSIONID cookie 值作为其各自 HttpSession 对象的键。所以事实上,不仅 HttpSession 对象在应用程序(servlet 上下文)级别上总是不同的和范围,而且在实践中,JSESSIONID 值也必须不同。对吗?

2如果是这样,那servlet规范为什么要用这样的写法:

底层机制,例如用于建立 会话,对于不同的上下文可以是相同的 [...]

我能想象到上述实现的唯一方法是有一种方法可以硬编码提供JSESSIONID 值以在创建新会话对象时使用?但我没有看到相关的 API。

3 有没有一种方法可以使用 XML 元素中的 / 路径在应用程序之间共享一些其他 cookie,但不能将 / 路径应用于 JSESSIONID cookie ?换句话说, 是应用于应用程序的所有 cookie 还是仅应用于会话跟踪的 cookie? (JSESSIONID) ?

【问题讨论】:

  • 您是如何将 cookie 的域设置为空白的?在第一个屏幕截图中,域是空白的;你有没有使用一些特定的配置?在我对 tomcat7 的测试中,cookie 域设置为服务器的主机名。谢谢。

标签: java session tomcat cookies


【解决方案1】:

经过进一步的实验并从this answer 中得到启发,似乎要为所有 Web 应用程序使用相同的 JSESSIONID,必须在 context.xml 中设置以下属性:

<Context ... sessionCookiePath="/">

任一 Tomcat 范围的 context.xml WAR 特定的 context.xml 都可以。 WAR 的 web.xml 中配置的 &lt;cookie-config&gt;&lt;path&gt; 值显然被忽略了。

关于我的问题的 3 点,我发现为其他 cookie 设置路径的方法是以编程方式创建其中的许多,每个路径一个,并将它们添加到响应对象中addCookie 方法。 web.xmlcontext.xml中的配置适用于会话cookie之外的其他cookie。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2017-04-18
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2018-01-02
    相关资源
    最近更新 更多