正确删除服务器端cookie的方法

Jos*_*unz 121 cookies http

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

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

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;
Run Code Online (Sandbox Code Playgroud)

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

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC; 
Run Code Online (Sandbox Code Playgroud)

这在Firefox上工作正常,但不会删除IE或Safari上的cookie.

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

Lek*_*eyn 193

使用; expires附加发送相同的cookie值不会破坏cookie.

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

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT
Run Code Online (Sandbox Code Playgroud)

请注意,您无法强制所有浏览器删除Cookie.客户端可以配置浏览器,使cookie保持不变,即使它已过期.如上所述设置值将解决该问题.

  • 我建议使用空文本作为垃圾,而不是"删除"`,以避免以后混淆可能合法的值等于"已删除" (45认同)
  • @raulk是的,你是对的.有趣的是它之前没有被注意到,希望它不会引起太多问题.yegor256,在大多数情况下,空值应该有效.相关:有些人可能想知道为什么即使在发送此标题后他们的cookie也不会被删除.在这种情况下,请查看来自其他域的cookie.例如,删除`foo = bar; domain = www.example.com`,另一个cookie`foo = qux; 将使用domain = .example.com`. (8认同)
  • -1 因为我从未见过配置浏览器以忽略 cookie 过期的方法,并且我不相信存在任何提供此类选项的浏览器。更重要的是,在@DaveJarvis 相当大胆的编辑之后,您的答案的第一句话现在对于任何主要浏览器或任何符合规范的用户代理都是完全错误的。https://tools.ietf.org/search/rfc6265#section-5.3 规定*“如果任何时候 cookie 存储中存在过期的 cookie,用户代理必须从 cookie 存储中驱逐所有过期的 cookie。”*据我所知,这实际上是每个浏览器所做的。 (4认同)
  • "客户端可以以这样的方式配置浏览器,即使cookie过期,也可以保持cookie.如上所述设置值可以解决这个问题." 客户端无法配置浏览器忽略您将cookie内容设置为"已删除"的请求吗?您无法强迫客户端执行任何不想要的操作. (3认同)

Mar*_*ery 15

在我撰写此答案时,此问题可接受答案似乎表明,当接收到Expires值为过去的替换cookie时,浏览器不需要删除cookie 。该说法是错误的。设置Expires为过去是删除Cookie的标准且符合规范的方式,规范要求用​​户代理遵守该规范。

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

最后,要删除cookie,服务器将返回一个Set-Cookie标头,其中包含过去的到期日期。仅当Set-Cookie标头中的Path和Domain属性与创建cookie时使用的值匹配时,服务器才能成功删除cookie。

用户代理要求”部分包括以下要求,如果用户代理收到的同名新Cookie的过期日期过去,则必须立即删除该Cookie。

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

    1. ...
    2. ...
    3. 更新新创建的cookie的创建时间以匹配旧cookie的创建时间。
    4. 从cookie存储区中删除旧cookie。
  2. 将新创建的cookie插入cookie存储。

如果cookie具有过去的过期日期,则cookie被“过期”。

如果任何时候在cookie存储中存在过期的cookie,则用户代理必须从cookie存储中逐出所有过期的cookie。

上面的点11-3、11-4和12一起表示,当接收到具有相同名称,域和路径的新cookie时,必须删除旧cookie并用新cookie替换。最后,关于过期cookie的以下几点进一步表明,完成此操作后,必须立即将 cookie 逐出。在这一点上,规范没有为浏览器提供任何回旋余地。如果浏览器向用户提供禁用cookie过期的选项,如公认的答案表明某些浏览器会这样做,则将违反规范。(这种功能也几乎没有用,据我所知它在任何浏览器中都不存在。)

那么,为什么这个问题的OP观察到这种方法失败了?尽管我没有清除Internet Explorer的副本来检查其行为,但我怀疑这是因为OP的Expires值格式不正确!他们使用了这个值:

expires=Thu, Jan 01 1970 00:00:00 UTC;
Run Code Online (Sandbox Code Playgroud)

但是,从两种角度来看,这在语法上是无效的。

规范的语法部分规定该Expires属性的值必须为

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

在上面的第二个链接之后,我们发现它是以下格式的示例:

Sun, 06 Nov 1994 08:49:37 GMT
Run Code Online (Sandbox Code Playgroud)

并找到语法定义...

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

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

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    
    Run Code Online (Sandbox Code Playgroud)

    并定义date1如下:

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    
    Run Code Online (Sandbox Code Playgroud)

  1. 不允许UTC作为时区。

    规范包含以下有关此格式可接受的时区偏移的声明:

    所有HTTP日期/时间戳都必须毫无例外地以格林威治标准时间(GMT)表示。

    更重要的是,如果我们深入研究此日期时间格式的原始规范,则会发现它在https://tools.ietf.org/html/rfc822的初始规范中,“ 语法”部分列出了“ UT”(表示“通用时间” )作为一个可能的值,但确实不是列表不UTC(世界协调时间)为有效。据我所知,以这种日期格式使用“ UTC” 从未有效。这不是一个有效的值时,在1982年第一次指定的格式,和HTTP规范已经通过严格通过禁止使用除“GMT”以外的所有“区”值的格式的限制版本。

如果这里的问题提问者已经代替了Expires属性,像这样的话:

expires=Thu, 01 Jan 1970 00:00:00 GMT;
Run Code Online (Sandbox Code Playgroud)

那么大概就可以了。

  • 一种更简洁的方法是生成这样的字符串。例如在 JS 中:`new Date(0).toUTCString()` (3认同)
  • 用户代理可以选择不遵循“必需”规则。接受的答案只是简单地说明,理论上,浏览器可以继续发送过期的 cookie。 (3认同)

irr*_*ble 12

将"过期"设置为过去日期是删除cookie的标准方法.

您的问题可能是因为日期格式不是传统的.IE可能只预计GMT.


小智 11

使用 Max-Age=-1 而不是“Expires”。它更短,对语法不那么挑剔,无论如何 Max-Age 优先于 Expires。

  • 使用“Max-Age=0”而不是“-1”值。 (6认同)
  • @tdjprog 请解释原因,因为两者都有效。“零或负数将使 cookie 立即过期”,来源:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie (6认同)
  • 你是对的@Musa。零或负数 (2认同)