【问题标题】:Cookie maxAge always -1Cookie maxAge 始终为 -1
【发布时间】:2016-07-15 04:16:37
【问题描述】:

我目前正在 JSF 中实现“自动登录”机制。实现了一个过滤器来拦截每个请求,并通过读取cookie来检查用户是否登录。

当用户第一次登录时,在托管bean中,cookie是这样保存的:

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
Cookie cookie = new Cookie("myCookieRef", value);
cookie.setPath("/");
cookie.setMaxAge(3600);
response.addCookie(cookie);

稍后如果用户执行重定向,在过滤器中,我使用以下代码检索 cookie:

Cookie[] cookies = request.getCookies();
if (cookies != null) 
{
   for (Cookie cookie : cookies)
   {
       if (name.equals("myCookieRef")) 
       {
          return cookie;
       }
    }
}

request 是 HttpServletRequest 对象。

问题是返回的 cookie 总是有一个 -1 maxAgenull value

不知道添加cookie时是否遗漏了什么,还是应该为cookie指定一些额外的属性?

非常感谢。

【问题讨论】:

    标签: jsf cookies


    【解决方案1】:

    客户端不会将名称和值以外的 cookie 属性发送回服务器。

    另见RFC6265 section 4.2.2(强调我的)。

    4.2.2。语义

    每个 cookie 对代表用户代理存储的一个 cookie。这 cookie-pair 包含用户代理的 cookie-name 和 cookie-value 在 Set-Cookie 标头中收到。

    请注意不返回 cookie 属性。特别是, 服务器无法单独从 Cookie 标头确定 cookie 将过期,cookie 对哪些主机有效, cookie 有效的路径,或者 cookie 是否设置为 Secure 或 HttpOnly 属性。

    最大年龄的行为与指定的一样。此外,如果它在客户端已经过期,那么整个 cookie 就不会从客户端发送到服务器。在服务器端,您通常只需设置一个具有相同名称/值的新 cookie 并在没有登录用户的情况下检查 cookie 是否存在,而不是是否存在,来延长每次“自动登录”时 cookie 的生命周期是否过期。

    如果由于其他原因最大年龄值对您非常重要,只需将其与唯一 cookie 标识符(cookie 值)一起存储在您身边的某个数据库中。

    至于null 值,这表明您自己的代码存在问题,而不是cookie 中的问题。这个问题在目前提供的信息中是看不到的,但我相信如果你再次检查/调试它,你会发现一个简单的错误。

    关于“自动登录”的具体功能需求,请阅读:How to implement "Stay Logged In" when user login in to the web application

    【讨论】:

    • 感谢您的回答。我还有一个问题:我首先通过选中“记住我”登录,然后退出,在退出之前,我检索 cookie,并在 HttpServletResponse 中将 maxAge 设置为 0。然后我再次登录,没有勾选“记住我”,这一次,在过滤器中,我仍然可以检索到相同的cookie,它是在第一次登录时创建的,我不知道为什么cookie仍然存在.此外,关于 cookie 名称,它应该始终是同一个吗?即使不同的用户登录?如果用户登录时没有勾选“记住我”,是否应该创建 cookie?
    • 显然您在不同的路径上有多个 cookie。一个常见的初学者错误是 cookie 路径从未明确设置,因此默认为 URL 中当前打开的文件夹。您应该将 cookie 路径显式设置为您希望此 cookie 可用的所有文件夹的公共父级。如果这是 webapp 的根文件夹,请设置 "/"。另见 a.o. stackoverflow.com/a/28177426
    • 我已将路径设置为“/”。对我来说很奇怪的是,第二次登录,在过滤器中,cookie 仍然存在,即使我在第一次注销期间在 HttpServletResponse 中将 maxAge 设置为 0。
    • 在继续测试之前清除网络浏览器中的所有 cookie,或者生成一个隐身窗口。
    • 这可能是我的错误,我没有清除 cookie....我稍后会尝试。谢谢。我还有一个问题,这是我测试过的一个场景:用户直接关闭浏览器,没有先点击注销(登录没有“记住我”),然后用户再次加载页面,在过滤器中,cookie请求中存在(正常,因为关闭浏览器时cookie maxAge没有变为0),并且用户自动登录,这不是我想要的。
    猜你喜欢
    • 2017-07-21
    • 2018-10-28
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多