正确的方式删除cookies服务器端

对于我的身份验证过程,当用户登录时,我创建一个唯一的令牌,并将其放入用于身份验证的cookie中。

所以我会从服务器发送这样的东西:

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

适用于所有浏览器。然后为了删除一个cookie,我发送了一个类似的cookie,其中expires字段设置为1970年1月1日

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC;

这在Firefox上运行良好,但在IE或Safari上却不能删除cookie。

那么,删除cookie的最佳方法是什么(最好不需要JavaScript)?设置过去过期的方法看起来很笨重。还有,为什么这个在FF中工作,但在IE或Safari中不工作?

228088 次浏览

发送带有; expires的相同cookie值不会破坏cookie。

通过设置一个空值并包含一个expires字段使cookie无效:

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

请注意,您不能强制所有浏览器删除cookie。客户端可以对浏览器进行配置,使cookie即使过期也能保存。如上所述设置值可以解决这个问题。

将“过期日期”设置为过去的日期是删除cookie的标准方法。

您的问题可能是因为日期格式不是常规的。IE可能只期待格林尼治时间。

对于GlassFish Jersey JAX-RS实现,我通过描述所有公共参数的通用方法解决了这个问题。至少三个参数必须相等:name(="name"), path(="/")和domain(=null):

public static NewCookie createDomainCookie(String value, int maxAgeInMinutes) {
ZonedDateTime time = ZonedDateTime.now().plusMinutes(maxAgeInMinutes);
Date expiry = time.toInstant().toEpochMilli();
NewCookie newCookie = new NewCookie("name", value, "/", null, Cookie.DEFAULT_VERSION,null, maxAgeInMinutes*60, expiry, false, false);
return newCookie;
}

并使用它的常用方式设置cookie:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie(token, 60);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

删除cookie:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie("", 0);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

在我写这个答案的时候,这个问题的公认答案似乎表明,当浏览器接收到一个Expires值是过去的替换cookie时,不需要删除cookie。这种说法是错误的。将Expires设置为过去是标准的、符合规范的删除cookie的方式,并且规范要求用户代理尊重它。

在过去使用Expires属性来删除cookie是正确的,并且是规范规定的删除cookie的方法。RFC 6265的示例部分指出:

最后,为了删除一个cookie,服务器返回一个Set-Cookie报头 在过去有个截止日期。服务器将会成功 在删除cookie时,只有路径和域属性在 Set-Cookie报头与cookie存在时使用的值匹配 创建。< / p >

用户代理需求部分包含以下要求,如果用户代理接收到一个具有相同名称且过期日期为过去的新cookie,则必须立即删除cookie

  1. 如果[当接收到一个新的cookie时],cookie存储中包含一个与新创建的cookie具有相同的名称、域和路径的cookie:

    1. ...
    2. ...
    3. 更新新创建的cookie的创建时间,以匹配旧cookie的创建时间。
    4. 把旧饼干从饼干店拿出来。
  2. 将新创建的cookie插入cookie存储区。

饼干“过期”了;如果cookie在过去有过期日期。

用户代理必须从cookie存储中清除所有过期的cookie

.如果在任何时候,cookie存储中存在过期的cookie

上面的11-3、11-4和12点表示,当接收到具有相同名称、域和路径的新cookie时,必须删除旧cookie,并用新cookie替换。最后,下面关于过期cookie的一点进一步说明,在此之后, cookie必须立即被清除。规范在这一点上没有给浏览器回旋的余地;如果一个浏览器向用户提供禁用cookie过期的选项,就像公认的答案所建议的一些浏览器那样,那么它就违反了规范(这样的功能也几乎没有用处,据我所知,在任何浏览器中都不存在这种功能)。

那么,为什么这个问题的OP观察到这种方法失败了呢?虽然我还没有打开ie浏览器来检查它的行为,但我怀疑这是因为OP的Expires值是畸形的!他们使用这个值:

expires=Thu, Jan 01 1970 00:00:00 UTC;

然而,这在两个方面是语法无效的。

规范的语法部分规定Expires属性的值必须是a

rfc1123-date,在[RFC2616],章节3.3.1中定义

在上面的第二个链接之后,我们发现这是一个格式的例子:

Sun, 06 Nov 1994 08:49:37 GMT

并发现语法定义…

  1. 要求日期以日月年格式书写,而不是提问者使用的月日年格式。

    具体来说,它定义rfc1123-date如下:

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    并像这样定义date1:

    date1        = 2DIGIT SP month SP 4DIGIT
    ; day month year (e.g., 02 Jun 1982)
    

而且

  1. 不允许UTC作为时区。

    该规范包含以下声明,说明在这种格式中哪些时区偏移是可接受的:

    所有HTTP日期/时间戳必须以格林尼治标准时间(GMT)表示,无一例外。

    更重要的是,如果我们深入挖掘这种datetime格式的原始规范,我们会发现在它的初始规范https://www.rfc-editor.org/rfc/rfc822中,语法部分列出了"UT"(意思是“通用时间”)作为可能的值,但是列出的不是UTC(协调世界时)。据我所知,使用"UTC"在此日期格式中从来没有是否有效;在1982年首次指定该格式时,它不是一个有效的值,并且HTTP规范通过禁止使用所有"zone"来严格采用该格式的更多的限制版本。“GMT"”以外的值。

如果这里的提问者使用了Expires属性,如,则:

expires=Thu, 01 Jan 1970 00:00:00 GMT;

那样的话,它大概会起作用。

< p >使用 信息= 1 而不是“过期”。它更短,对语法不那么挑剔,而且Max-Age优先于Expires